remove accidentally tracked node_modules, update gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9528700862
commit
34aa8190d6
3
.gitignore
vendored
3
.gitignore
vendored
@ -65,7 +65,10 @@ berrypod-*.tar
|
|||||||
|
|
||||||
# In case you use Node.js/npm, you want to ignore these.
|
# In case you use Node.js/npm, you want to ignore these.
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
node_modules/
|
||||||
/assets/node_modules/
|
/assets/node_modules/
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
# Environment variables (API tokens, secrets)
|
# Environment variables (API tokens, secrets)
|
||||||
.env
|
.env
|
||||||
|
|||||||
1
node_modules/.bin/pixelmatch
generated
vendored
1
node_modules/.bin/pixelmatch
generated
vendored
@ -1 +0,0 @@
|
|||||||
../pixelmatch/bin/pixelmatch
|
|
||||||
30
node_modules/.package-lock.json
generated
vendored
30
node_modules/.package-lock.json
generated
vendored
@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "simpleshop_theme",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"node_modules/pixelmatch": {
|
|
||||||
"version": "7.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-7.1.0.tgz",
|
|
||||||
"integrity": "sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"pngjs": "^7.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"pixelmatch": "bin/pixelmatch"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pngjs": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.19.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
15
node_modules/pixelmatch/LICENSE
generated
vendored
15
node_modules/pixelmatch/LICENSE
generated
vendored
@ -1,15 +0,0 @@
|
|||||||
ISC License
|
|
||||||
|
|
||||||
Copyright (c) 2025, Mapbox
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
||||||
with or without fee is hereby granted, provided that the above copyright notice
|
|
||||||
and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
||||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
||||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
||||||
THIS SOFTWARE.
|
|
||||||
111
node_modules/pixelmatch/README.md
generated
vendored
111
node_modules/pixelmatch/README.md
generated
vendored
@ -1,111 +0,0 @@
|
|||||||
# pixelmatch
|
|
||||||
|
|
||||||
[](https://github.com/mapbox/pixelmatch/actions/workflows/node.yml)
|
|
||||||
[](https://github.com/mourner/projects)
|
|
||||||
|
|
||||||
The smallest, simplest and fastest JavaScript pixel-level image comparison library,
|
|
||||||
originally created to compare screenshots in tests.
|
|
||||||
|
|
||||||
Features accurate **anti-aliased pixels detection**
|
|
||||||
and **perceptual color difference metrics**.
|
|
||||||
|
|
||||||
Inspired by [Resemble.js](https://github.com/Huddle/Resemble.js)
|
|
||||||
and [Blink-diff](https://github.com/yahoo/blink-diff).
|
|
||||||
Unlike these libraries, pixelmatch is around **150 lines of code**,
|
|
||||||
has **no dependencies**, and works on **raw typed arrays** of image data,
|
|
||||||
so it's **blazing fast** and can be used in **any environment** (Node or browsers).
|
|
||||||
|
|
||||||
```js
|
|
||||||
const numDiffPixels = pixelmatch(img1, img2, diff, 800, 600, {threshold: 0.1});
|
|
||||||
```
|
|
||||||
|
|
||||||
Implements ideas from the following papers:
|
|
||||||
|
|
||||||
- [Measuring perceived color difference using YIQ NTSC transmission color space in mobile applications](http://www.progmat.uaem.mx:8080/artVol2Num2/Articulo3Vol2Num2.pdf) (2010, Yuriy Kotsarenko, Fernando Ramos)
|
|
||||||
- [Anti-aliased pixel and intensity slope detector](https://www.researchgate.net/publication/234126755_Anti-aliased_Pixel_and_Intensity_Slope_Detector) (2009, Vytautas Vyšniauskas)
|
|
||||||
|
|
||||||
## [Demo](https://observablehq.com/@mourner/pixelmatch-demo)
|
|
||||||
|
|
||||||
## Example output
|
|
||||||
|
|
||||||
| expected | actual | diff |
|
|
||||||
| --- | --- | --- |
|
|
||||||
|  |  |  |
|
|
||||||
|  |  |  |
|
|
||||||
|  |  |  |
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### pixelmatch(img1, img2, output, width, height[, options])
|
|
||||||
|
|
||||||
- `img1`, `img2` — Image data of the images to compare (`Buffer`, `Uint8Array` or `Uint8ClampedArray`). **Note:** image dimensions must be equal.
|
|
||||||
- `output` — Image data to write the diff to, or `null` if don't need a diff image.
|
|
||||||
- `width`, `height` — Width and height of the images. Note that _all three images_ need to have the same dimensions.
|
|
||||||
|
|
||||||
`options` is an object literal with the following properties:
|
|
||||||
|
|
||||||
- `threshold` — Matching threshold, ranges from `0` to `1`. Smaller values make the comparison more sensitive. `0.1` by default.
|
|
||||||
- `includeAA` — If `true`, disables detecting and ignoring anti-aliased pixels. `false` by default.
|
|
||||||
- `alpha` — Blending factor of unchanged pixels in the diff output. Ranges from `0` for pure white to `1` for original brightness. `0.1` by default.
|
|
||||||
- `aaColor` — The color of anti-aliased pixels in the diff output in `[R, G, B]` format. `[255, 255, 0]` by default.
|
|
||||||
- `diffColor` — The color of differing pixels in the diff output in `[R, G, B]` format. `[255, 0, 0]` by default.
|
|
||||||
- `diffColorAlt` — An alternative color to use for dark on light differences to differentiate between "added" and "removed" parts. If not provided, all differing pixels use the color specified by `diffColor`. `null` by default.
|
|
||||||
- `diffMask` — Draw the diff over a transparent background (a mask), rather than over the original image. Will not draw anti-aliased pixels (if detected).
|
|
||||||
|
|
||||||
Compares two images, writes the output diff and returns the number of mismatched pixels.
|
|
||||||
|
|
||||||
## Command line
|
|
||||||
|
|
||||||
Pixelmatch comes with a binary that works with PNG images:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pixelmatch image1.png image2.png output.png 0.1
|
|
||||||
```
|
|
||||||
|
|
||||||
## Example usage
|
|
||||||
|
|
||||||
### Node.js
|
|
||||||
|
|
||||||
```js
|
|
||||||
import fs from 'fs';
|
|
||||||
import {PNG} from 'pngjs';
|
|
||||||
import pixelmatch from 'pixelmatch';
|
|
||||||
|
|
||||||
const img1 = PNG.sync.read(fs.readFileSync('img1.png'));
|
|
||||||
const img2 = PNG.sync.read(fs.readFileSync('img2.png'));
|
|
||||||
const {width, height} = img1;
|
|
||||||
const diff = new PNG({width, height});
|
|
||||||
|
|
||||||
pixelmatch(img1.data, img2.data, diff.data, width, height, {threshold: 0.1});
|
|
||||||
|
|
||||||
fs.writeFileSync('diff.png', PNG.sync.write(diff));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Browsers
|
|
||||||
|
|
||||||
```js
|
|
||||||
const img1 = img1Context.getImageData(0, 0, width, height);
|
|
||||||
const img2 = img2Context.getImageData(0, 0, width, height);
|
|
||||||
const diff = diffContext.createImageData(width, height);
|
|
||||||
|
|
||||||
pixelmatch(img1.data, img2.data, diff.data, width, height, {threshold: 0.1});
|
|
||||||
|
|
||||||
diffContext.putImageData(diff, 0, 0);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
Install with NPM:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install pixelmatch
|
|
||||||
```
|
|
||||||
|
|
||||||
Or use in the browser from a CDN:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script type="module">
|
|
||||||
import pixelmatch from 'https://esm.run/pixelmatch';
|
|
||||||
```
|
|
||||||
|
|
||||||
## [Changelog](https://github.com/mapbox/pixelmatch/releases)
|
|
||||||
39
node_modules/pixelmatch/bin/pixelmatch
generated
vendored
39
node_modules/pixelmatch/bin/pixelmatch
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
import {PNG} from 'pngjs';
|
|
||||||
import fs from 'fs';
|
|
||||||
import match from '../index.js';
|
|
||||||
|
|
||||||
if (process.argv.length < 4) {
|
|
||||||
console.log('Usage: pixelmatch image1.png image2.png [diff.png] [threshold] [includeAA]');
|
|
||||||
process.exit(64);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [,, img1Path, img2Path, diffPath, threshold, includeAA] = process.argv;
|
|
||||||
const options = {};
|
|
||||||
if (threshold !== undefined) options.threshold = +threshold;
|
|
||||||
if (includeAA !== undefined) options.includeAA = includeAA !== 'false';
|
|
||||||
|
|
||||||
const img1 = PNG.sync.read(fs.readFileSync(img1Path));
|
|
||||||
const img2 = PNG.sync.read(fs.readFileSync(img2Path));
|
|
||||||
|
|
||||||
const {width, height} = img1;
|
|
||||||
|
|
||||||
if (img2.width !== width || img2.height !== height) {
|
|
||||||
console.log(`Image dimensions do not match: ${width}x${height} vs ${img2.width}x${img2.height}`);
|
|
||||||
process.exit(65);
|
|
||||||
}
|
|
||||||
|
|
||||||
const diff = diffPath ? new PNG({width, height}) : null;
|
|
||||||
|
|
||||||
console.time('matched in');
|
|
||||||
const diffs = match(img1.data, img2.data, diff ? diff.data : null, width, height, options);
|
|
||||||
console.timeEnd('matched in');
|
|
||||||
|
|
||||||
console.log(`different pixels: ${diffs}`);
|
|
||||||
console.log(`error: ${Math.round(100 * 100 * diffs / (width * height)) / 100}%`);
|
|
||||||
|
|
||||||
if (diff) {
|
|
||||||
fs.writeFileSync(diffPath, PNG.sync.write(diff));
|
|
||||||
}
|
|
||||||
process.exit(diffs ? 66 : 0);
|
|
||||||
29
node_modules/pixelmatch/index.d.ts
generated
vendored
29
node_modules/pixelmatch/index.d.ts
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* Compare two equally sized images, pixel by pixel.
|
|
||||||
*
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} img1 First image data.
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} img2 Second image data.
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray | void} output Image data to write the diff to, if provided.
|
|
||||||
* @param {number} width Input images width.
|
|
||||||
* @param {number} height Input images height.
|
|
||||||
*
|
|
||||||
* @param {Object} [options]
|
|
||||||
* @param {number} [options.threshold=0.1] Matching threshold (0 to 1); smaller is more sensitive.
|
|
||||||
* @param {boolean} [options.includeAA=false] Whether to skip anti-aliasing detection.
|
|
||||||
* @param {number} [options.alpha=0.1] Opacity of original image in diff output.
|
|
||||||
* @param {[number, number, number]} [options.aaColor=[255, 255, 0]] Color of anti-aliased pixels in diff output.
|
|
||||||
* @param {[number, number, number]} [options.diffColor=[255, 0, 0]] Color of different pixels in diff output.
|
|
||||||
* @param {[number, number, number]} [options.diffColorAlt=options.diffColor] Whether to detect dark on light differences between img1 and img2 and set an alternative color to differentiate between the two.
|
|
||||||
* @param {boolean} [options.diffMask=false] Draw the diff over a transparent background (a mask).
|
|
||||||
*
|
|
||||||
* @return {number} The number of mismatched pixels.
|
|
||||||
*/
|
|
||||||
export default function pixelmatch(img1: Uint8Array | Uint8ClampedArray, img2: Uint8Array | Uint8ClampedArray, output: Uint8Array | Uint8ClampedArray | void, width: number, height: number, options?: {
|
|
||||||
threshold?: number | undefined;
|
|
||||||
includeAA?: boolean | undefined;
|
|
||||||
alpha?: number | undefined;
|
|
||||||
aaColor?: [number, number, number] | undefined;
|
|
||||||
diffColor?: [number, number, number] | undefined;
|
|
||||||
diffColorAlt?: [number, number, number] | undefined;
|
|
||||||
diffMask?: boolean | undefined;
|
|
||||||
}): number;
|
|
||||||
271
node_modules/pixelmatch/index.js
generated
vendored
271
node_modules/pixelmatch/index.js
generated
vendored
@ -1,271 +0,0 @@
|
|||||||
/**
|
|
||||||
* Compare two equally sized images, pixel by pixel.
|
|
||||||
*
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} img1 First image data.
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} img2 Second image data.
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray | void} output Image data to write the diff to, if provided.
|
|
||||||
* @param {number} width Input images width.
|
|
||||||
* @param {number} height Input images height.
|
|
||||||
*
|
|
||||||
* @param {Object} [options]
|
|
||||||
* @param {number} [options.threshold=0.1] Matching threshold (0 to 1); smaller is more sensitive.
|
|
||||||
* @param {boolean} [options.includeAA=false] Whether to skip anti-aliasing detection.
|
|
||||||
* @param {number} [options.alpha=0.1] Opacity of original image in diff output.
|
|
||||||
* @param {[number, number, number]} [options.aaColor=[255, 255, 0]] Color of anti-aliased pixels in diff output.
|
|
||||||
* @param {[number, number, number]} [options.diffColor=[255, 0, 0]] Color of different pixels in diff output.
|
|
||||||
* @param {[number, number, number]} [options.diffColorAlt=options.diffColor] Whether to detect dark on light differences between img1 and img2 and set an alternative color to differentiate between the two.
|
|
||||||
* @param {boolean} [options.diffMask=false] Draw the diff over a transparent background (a mask).
|
|
||||||
*
|
|
||||||
* @return {number} The number of mismatched pixels.
|
|
||||||
*/
|
|
||||||
export default function pixelmatch(img1, img2, output, width, height, options = {}) {
|
|
||||||
const {
|
|
||||||
threshold = 0.1,
|
|
||||||
alpha = 0.1,
|
|
||||||
aaColor = [255, 255, 0],
|
|
||||||
diffColor = [255, 0, 0],
|
|
||||||
includeAA, diffColorAlt, diffMask
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
if (!isPixelData(img1) || !isPixelData(img2) || (output && !isPixelData(output)))
|
|
||||||
throw new Error('Image data: Uint8Array, Uint8ClampedArray or Buffer expected.');
|
|
||||||
|
|
||||||
if (img1.length !== img2.length || (output && output.length !== img1.length))
|
|
||||||
throw new Error('Image sizes do not match.');
|
|
||||||
|
|
||||||
if (img1.length !== width * height * 4) throw new Error('Image data size does not match width/height.');
|
|
||||||
|
|
||||||
// check if images are identical
|
|
||||||
const len = width * height;
|
|
||||||
const a32 = new Uint32Array(img1.buffer, img1.byteOffset, len);
|
|
||||||
const b32 = new Uint32Array(img2.buffer, img2.byteOffset, len);
|
|
||||||
let identical = true;
|
|
||||||
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
if (a32[i] !== b32[i]) { identical = false; break; }
|
|
||||||
}
|
|
||||||
if (identical) { // fast path if identical
|
|
||||||
if (output && !diffMask) {
|
|
||||||
for (let i = 0; i < len; i++) drawGrayPixel(img1, 4 * i, alpha, output);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maximum acceptable square distance between two colors;
|
|
||||||
// 35215 is the maximum possible value for the YIQ difference metric
|
|
||||||
const maxDelta = 35215 * threshold * threshold;
|
|
||||||
const [aaR, aaG, aaB] = aaColor;
|
|
||||||
const [diffR, diffG, diffB] = diffColor;
|
|
||||||
const [altR, altG, altB] = diffColorAlt || diffColor;
|
|
||||||
let diff = 0;
|
|
||||||
|
|
||||||
// compare each pixel of one image against the other one
|
|
||||||
for (let y = 0; y < height; y++) {
|
|
||||||
for (let x = 0; x < width; x++) {
|
|
||||||
|
|
||||||
const i = y * width + x;
|
|
||||||
const pos = i * 4;
|
|
||||||
|
|
||||||
// squared YUV distance between colors at this pixel position, negative if the img2 pixel is darker
|
|
||||||
const delta = a32[i] === b32[i] ? 0 : colorDelta(img1, img2, pos, pos, false);
|
|
||||||
|
|
||||||
// the color difference is above the threshold
|
|
||||||
if (Math.abs(delta) > maxDelta) {
|
|
||||||
// check it's a real rendering difference or just anti-aliasing
|
|
||||||
const isAA = antialiased(img1, x, y, width, height, a32, b32) || antialiased(img2, x, y, width, height, b32, a32);
|
|
||||||
if (!includeAA && isAA) {
|
|
||||||
// one of the pixels is anti-aliasing; draw as yellow and do not count as difference
|
|
||||||
// note that we do not include such pixels in a mask
|
|
||||||
if (output && !diffMask) drawPixel(output, pos, aaR, aaG, aaB);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// found substantial difference not caused by anti-aliasing; draw it as such
|
|
||||||
if (output) {
|
|
||||||
if (delta < 0) {
|
|
||||||
drawPixel(output, pos, altR, altG, altB);
|
|
||||||
} else {
|
|
||||||
drawPixel(output, pos, diffR, diffG, diffB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (output && !diffMask) {
|
|
||||||
// pixels are similar; draw background as grayscale image blended with white
|
|
||||||
drawGrayPixel(img1, pos, alpha, output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the number of different pixels
|
|
||||||
return diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {Uint8Array | Uint8ClampedArray} arr */
|
|
||||||
function isPixelData(arr) {
|
|
||||||
// work around instanceof Uint8Array not working properly in some Jest environments
|
|
||||||
return ArrayBuffer.isView(arr) && arr.BYTES_PER_ELEMENT === 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a pixel is likely a part of anti-aliasing;
|
|
||||||
* based on "Anti-aliased Pixel and Intensity Slope Detector" paper by V. Vysniauskas, 2009
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} img
|
|
||||||
* @param {number} x1
|
|
||||||
* @param {number} y1
|
|
||||||
* @param {number} width
|
|
||||||
* @param {number} height
|
|
||||||
* @param {Uint32Array} a32
|
|
||||||
* @param {Uint32Array} b32
|
|
||||||
*/
|
|
||||||
function antialiased(img, x1, y1, width, height, a32, b32) {
|
|
||||||
const x0 = Math.max(x1 - 1, 0);
|
|
||||||
const y0 = Math.max(y1 - 1, 0);
|
|
||||||
const x2 = Math.min(x1 + 1, width - 1);
|
|
||||||
const y2 = Math.min(y1 + 1, height - 1);
|
|
||||||
const pos = y1 * width + x1;
|
|
||||||
let zeroes = x1 === x0 || x1 === x2 || y1 === y0 || y1 === y2 ? 1 : 0;
|
|
||||||
let min = 0;
|
|
||||||
let max = 0;
|
|
||||||
let minX = 0;
|
|
||||||
let minY = 0;
|
|
||||||
let maxX = 0;
|
|
||||||
let maxY = 0;
|
|
||||||
|
|
||||||
// go through 8 adjacent pixels
|
|
||||||
for (let x = x0; x <= x2; x++) {
|
|
||||||
for (let y = y0; y <= y2; y++) {
|
|
||||||
if (x === x1 && y === y1) continue;
|
|
||||||
|
|
||||||
// brightness delta between the center pixel and adjacent one
|
|
||||||
const delta = colorDelta(img, img, pos * 4, (y * width + x) * 4, true);
|
|
||||||
|
|
||||||
// count the number of equal, darker and brighter adjacent pixels
|
|
||||||
if (delta === 0) {
|
|
||||||
zeroes++;
|
|
||||||
// if found more than 2 equal siblings, it's definitely not anti-aliasing
|
|
||||||
if (zeroes > 2) return false;
|
|
||||||
|
|
||||||
// remember the darkest pixel
|
|
||||||
} else if (delta < min) {
|
|
||||||
min = delta;
|
|
||||||
minX = x;
|
|
||||||
minY = y;
|
|
||||||
|
|
||||||
// remember the brightest pixel
|
|
||||||
} else if (delta > max) {
|
|
||||||
max = delta;
|
|
||||||
maxX = x;
|
|
||||||
maxY = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there are no both darker and brighter pixels among siblings, it's not anti-aliasing
|
|
||||||
if (min === 0 || max === 0) return false;
|
|
||||||
|
|
||||||
// if either the darkest or the brightest pixel has 3+ equal siblings in both images
|
|
||||||
// (definitely not anti-aliased), this pixel is anti-aliased
|
|
||||||
return (hasManySiblings(a32, minX, minY, width, height) && hasManySiblings(b32, minX, minY, width, height)) ||
|
|
||||||
(hasManySiblings(a32, maxX, maxY, width, height) && hasManySiblings(b32, maxX, maxY, width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a pixel has 3+ adjacent pixels of the same color.
|
|
||||||
* @param {Uint32Array} img
|
|
||||||
* @param {number} x1
|
|
||||||
* @param {number} y1
|
|
||||||
* @param {number} width
|
|
||||||
* @param {number} height
|
|
||||||
*/
|
|
||||||
function hasManySiblings(img, x1, y1, width, height) {
|
|
||||||
const x0 = Math.max(x1 - 1, 0);
|
|
||||||
const y0 = Math.max(y1 - 1, 0);
|
|
||||||
const x2 = Math.min(x1 + 1, width - 1);
|
|
||||||
const y2 = Math.min(y1 + 1, height - 1);
|
|
||||||
const val = img[y1 * width + x1];
|
|
||||||
let zeroes = x1 === x0 || x1 === x2 || y1 === y0 || y1 === y2 ? 1 : 0;
|
|
||||||
|
|
||||||
// go through 8 adjacent pixels
|
|
||||||
for (let x = x0; x <= x2; x++) {
|
|
||||||
for (let y = y0; y <= y2; y++) {
|
|
||||||
if (x === x1 && y === y1) continue;
|
|
||||||
zeroes += +(val === img[y * width + x]);
|
|
||||||
if (zeroes > 2) return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate color difference according to the paper "Measuring perceived color difference
|
|
||||||
* using YIQ NTSC transmission color space in mobile applications" by Y. Kotsarenko and F. Ramos
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} img1
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} img2
|
|
||||||
* @param {number} k
|
|
||||||
* @param {number} m
|
|
||||||
* @param {boolean} yOnly
|
|
||||||
*/
|
|
||||||
function colorDelta(img1, img2, k, m, yOnly) {
|
|
||||||
const r1 = img1[k];
|
|
||||||
const g1 = img1[k + 1];
|
|
||||||
const b1 = img1[k + 2];
|
|
||||||
const a1 = img1[k + 3];
|
|
||||||
const r2 = img2[m];
|
|
||||||
const g2 = img2[m + 1];
|
|
||||||
const b2 = img2[m + 2];
|
|
||||||
const a2 = img2[m + 3];
|
|
||||||
|
|
||||||
let dr = r1 - r2;
|
|
||||||
let dg = g1 - g2;
|
|
||||||
let db = b1 - b2;
|
|
||||||
const da = a1 - a2;
|
|
||||||
|
|
||||||
if (!dr && !dg && !db && !da) return 0;
|
|
||||||
|
|
||||||
if (a1 < 255 || a2 < 255) { // blend pixels with background
|
|
||||||
const rb = 48 + 159 * (k % 2);
|
|
||||||
const gb = 48 + 159 * ((k / 1.618033988749895 | 0) % 2);
|
|
||||||
const bb = 48 + 159 * ((k / 2.618033988749895 | 0) % 2);
|
|
||||||
dr = (r1 * a1 - r2 * a2 - rb * da) / 255;
|
|
||||||
dg = (g1 * a1 - g2 * a2 - gb * da) / 255;
|
|
||||||
db = (b1 * a1 - b2 * a2 - bb * da) / 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
const y = dr * 0.29889531 + dg * 0.58662247 + db * 0.11448223;
|
|
||||||
|
|
||||||
if (yOnly) return y; // brightness difference only
|
|
||||||
|
|
||||||
const i = dr * 0.59597799 - dg * 0.27417610 - db * 0.32180189;
|
|
||||||
const q = dr * 0.21147017 - dg * 0.52261711 + db * 0.31114694;
|
|
||||||
|
|
||||||
const delta = 0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q;
|
|
||||||
|
|
||||||
// encode whether the pixel lightens or darkens in the sign
|
|
||||||
return y > 0 ? -delta : delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} output
|
|
||||||
* @param {number} pos
|
|
||||||
* @param {number} r
|
|
||||||
* @param {number} g
|
|
||||||
* @param {number} b
|
|
||||||
*/
|
|
||||||
function drawPixel(output, pos, r, g, b) {
|
|
||||||
output[pos + 0] = r;
|
|
||||||
output[pos + 1] = g;
|
|
||||||
output[pos + 2] = b;
|
|
||||||
output[pos + 3] = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} img
|
|
||||||
* @param {number} i
|
|
||||||
* @param {number} alpha
|
|
||||||
* @param {Uint8Array | Uint8ClampedArray} output
|
|
||||||
*/
|
|
||||||
function drawGrayPixel(img, i, alpha, output) {
|
|
||||||
const val = 255 + (img[i] * 0.29889531 + img[i + 1] * 0.58662247 + img[i + 2] * 0.11448223 - 255) * alpha * img[i + 3] / 255;
|
|
||||||
drawPixel(output, i, val, val, val);
|
|
||||||
}
|
|
||||||
42
node_modules/pixelmatch/package.json
generated
vendored
42
node_modules/pixelmatch/package.json
generated
vendored
@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "pixelmatch",
|
|
||||||
"version": "7.1.0",
|
|
||||||
"type": "module",
|
|
||||||
"description": "The smallest and fastest pixel-level image comparison library.",
|
|
||||||
"main": "index.js",
|
|
||||||
"types": "index.d.ts",
|
|
||||||
"bin": {
|
|
||||||
"pixelmatch": "bin/pixelmatch"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"bin/pixelmatch",
|
|
||||||
"index.d.ts"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"pngjs": "^7.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^9.20.1",
|
|
||||||
"eslint-config-mourner": "^4.0.2",
|
|
||||||
"typescript": "^5.7.3"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"pretest": "eslint",
|
|
||||||
"test": "tsc && node --test"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/mapbox/pixelmatch.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"image",
|
|
||||||
"comparison",
|
|
||||||
"diff"
|
|
||||||
],
|
|
||||||
"author": "Volodymyr Agafonkin",
|
|
||||||
"license": "ISC",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/mapbox/pixelmatch/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/mapbox/pixelmatch#readme"
|
|
||||||
}
|
|
||||||
128
node_modules/pngjs/CHANGELOG.md
generated
vendored
128
node_modules/pngjs/CHANGELOG.md
generated
vendored
@ -1,128 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
### 7.0.0 - 19/02/2023
|
|
||||||
|
|
||||||
- BREAKING - Drop support for node 12 (Though nothing incompatible in this release yet)
|
|
||||||
- Switch to a pngjs organisation
|
|
||||||
|
|
||||||
### 6.0.0 - 24/10/2020
|
|
||||||
|
|
||||||
- BREAKING - Sync version now throws if there is unexpected content at the end of the stream.
|
|
||||||
- BREAKING - Drop support for node 10 (Though nothing incompatible in this release yet)
|
|
||||||
- Reduce the number of files included in the package
|
|
||||||
|
|
||||||
### 5.1.0 - 13/09/2020
|
|
||||||
|
|
||||||
- Add option to skip rescaling
|
|
||||||
|
|
||||||
### 5.0.0 - 15/04/2020
|
|
||||||
|
|
||||||
- Drop support for Node 8
|
|
||||||
- Browserified bundle may now contain ES20(15-20) code if the supported node version supports it. Please run the browserified version through babel if you need to support older browsers.
|
|
||||||
|
|
||||||
### 4.0.1 - 15/04/2020
|
|
||||||
|
|
||||||
- Fix to possible null reference in nextTick of async method
|
|
||||||
|
|
||||||
### 4.0.0 - 09/04/2020
|
|
||||||
|
|
||||||
- Fix issue in newer nodes with using Buffer
|
|
||||||
- Fix async issue with some png files
|
|
||||||
- Drop support for Node 4 & 6
|
|
||||||
|
|
||||||
### 3.4.0 - 09/03/2019
|
|
||||||
|
|
||||||
- Include whether the png has alpha in the meta data
|
|
||||||
- emit an error if the image is truncated instead of hanging
|
|
||||||
- Add a browserified version
|
|
||||||
- speed up some mapping functions
|
|
||||||
|
|
||||||
### 3.3.3 - 19/04/2018
|
|
||||||
|
|
||||||
- Real fix for node 9
|
|
||||||
|
|
||||||
### 3.3.2 - 16/02/2018
|
|
||||||
|
|
||||||
- Fix for node 9
|
|
||||||
|
|
||||||
### 3.3.1 - 15/11/2017
|
|
||||||
|
|
||||||
- Bugfixes and removal of es6
|
|
||||||
|
|
||||||
### 3.3.0
|
|
||||||
|
|
||||||
- Add writing 16 bit channels and support for grayscale input
|
|
||||||
|
|
||||||
### 3.2.0 - 30/04/2017
|
|
||||||
|
|
||||||
- Support for encoding 8-bit grayscale images
|
|
||||||
|
|
||||||
### 3.1.0 - 30/04/2017
|
|
||||||
|
|
||||||
- Support for pngs with zlib chunks that are malformed after valid data
|
|
||||||
|
|
||||||
### 3.0.1 - 16/02/2017
|
|
||||||
|
|
||||||
- Fix single pixel pngs
|
|
||||||
|
|
||||||
### 3.0.0 - 03/08/2016
|
|
||||||
|
|
||||||
- Drop support for node below v4 and iojs. Pin to 2.3.0 to use with old, unsupported or patched node versions.
|
|
||||||
|
|
||||||
### 2.3.0 - 22/04/2016
|
|
||||||
|
|
||||||
- Support for sync in node 0.10
|
|
||||||
|
|
||||||
### 2.2.0 - 04/12/2015
|
|
||||||
|
|
||||||
- Add sync write api
|
|
||||||
- Fix newfile example
|
|
||||||
- Correct comparison table
|
|
||||||
|
|
||||||
### 2.1.0 - 28/10/2015
|
|
||||||
|
|
||||||
- rename package to pngjs
|
|
||||||
- added 'bgColor' option
|
|
||||||
|
|
||||||
### 2.0.0 - 08/10/2015
|
|
||||||
|
|
||||||
- fixes to readme
|
|
||||||
- _breaking change_ - bitblt on the png prototype now doesn't take a unused, unnecessary src first argument
|
|
||||||
|
|
||||||
### 1.2.0 - 13/09/2015
|
|
||||||
|
|
||||||
- support passing colorType to write PNG's and writing bitmaps without alpha information
|
|
||||||
|
|
||||||
### 1.1.0 - 07/09/2015
|
|
||||||
|
|
||||||
- support passing a deflate factory for controlled compression
|
|
||||||
|
|
||||||
### 1.0.2 - 22/08/2015
|
|
||||||
|
|
||||||
- Expose all PNG creation info
|
|
||||||
|
|
||||||
### 1.0.1 - 21/08/2015
|
|
||||||
|
|
||||||
- Fix non square interlaced files
|
|
||||||
|
|
||||||
### 1.0.0 - 08/08/2015
|
|
||||||
|
|
||||||
- More tests
|
|
||||||
- source linted
|
|
||||||
- maintainability refactorings
|
|
||||||
- async API - exceptions in reading now emit warnings
|
|
||||||
- documentation improvement - sync api now documented, adjustGamma documented
|
|
||||||
- breaking change - gamma chunk is now written. previously a read then write would destroy gamma information, now it is persisted.
|
|
||||||
|
|
||||||
### 0.0.3 - 03/08/2015
|
|
||||||
|
|
||||||
- Error handling fixes
|
|
||||||
- ignore files for smaller npm footprint
|
|
||||||
|
|
||||||
### 0.0.2 - 02/08/2015
|
|
||||||
|
|
||||||
- Bugfixes to interlacing, support for transparent colours
|
|
||||||
|
|
||||||
### 0.0.1 - 02/08/2015
|
|
||||||
|
|
||||||
- Initial release, see pngjs for older changelog.
|
|
||||||
20
node_modules/pngjs/LICENSE
generated
vendored
20
node_modules/pngjs/LICENSE
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
pngjs original work Copyright (c) 2015 Luke Page & Original Contributors
|
|
||||||
pngjs derived work Copyright (c) 2012 Kuba Niegowski
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
287
node_modules/pngjs/README.md
generated
vendored
287
node_modules/pngjs/README.md
generated
vendored
@ -1,287 +0,0 @@
|
|||||||
 [](https://codecov.io/gh/pngjs/pngjs) [](http://badge.fury.io/js/pngjs)
|
|
||||||
|
|
||||||
# pngjs
|
|
||||||
|
|
||||||
Simple PNG encoder/decoder for Node.js with no dependencies.
|
|
||||||
|
|
||||||
Based on the original [pngjs](https://github.com/niegowski/node-pngjs) with the follow enhancements.
|
|
||||||
|
|
||||||
- Support for reading 1,2,4 & 16 bit files
|
|
||||||
- Support for reading interlace files
|
|
||||||
- Support for reading `tTRNS` transparent colours
|
|
||||||
- Support for writing colortype 0 (grayscale), colortype 2 (RGB), colortype 4 (grayscale alpha) and colortype 6 (RGBA)
|
|
||||||
- Sync interface as well as async
|
|
||||||
- API compatible with pngjs and node-pngjs
|
|
||||||
|
|
||||||
Known lack of support for:
|
|
||||||
|
|
||||||
- Extended PNG e.g. Animation
|
|
||||||
- Writing in colortype 3 (indexed color)
|
|
||||||
|
|
||||||
# Table of Contents
|
|
||||||
|
|
||||||
- [Requirements](#requirements)
|
|
||||||
- [Comparison Table](#comparison-table)
|
|
||||||
- [Tests](#tests)
|
|
||||||
- [Installation](#installation)
|
|
||||||
- [Browser](#browser)
|
|
||||||
- [Example](#example)
|
|
||||||
- [Async API](#async-api)
|
|
||||||
- [Sync API](#sync-api)
|
|
||||||
- [Changelog](#changelog)
|
|
||||||
|
|
||||||
# Comparison Table
|
|
||||||
|
|
||||||
| Name | Forked From | Sync | Async | 16 Bit | 1/2/4 Bit | Interlace | Gamma | Encodes | Tested |
|
|
||||||
| ------------- | ----------- | ---- | ----- | ------ | --------- | --------- | ------ | ------- | ------ |
|
|
||||||
| pngjs | | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
|
|
||||||
| node-png | pngjs | No | Yes | No | No | No | Hidden | Yes | Manual |
|
|
||||||
| png-coder | pngjs | No | Yes | Yes | No | No | Hidden | Yes | Manual |
|
|
||||||
| pngparse | | No | Yes | No | Yes | No | No | No | Yes |
|
|
||||||
| pngparse-sync | pngparse | Yes | No | No | Yes | No | No | No | Yes |
|
|
||||||
| png-async | | No | Yes | No | No | No | No | Yes | Yes |
|
|
||||||
| png-js | | No | Yes | No | No | No | No | No | No |
|
|
||||||
|
|
||||||
Native C++ node decoders:
|
|
||||||
|
|
||||||
- png
|
|
||||||
- png-sync (sync version of above)
|
|
||||||
- pixel-png
|
|
||||||
- png-img
|
|
||||||
|
|
||||||
# Tests
|
|
||||||
|
|
||||||
Tested using [PNG Suite](http://www.schaik.com/pngsuite/). We read every file into pngjs, output it in standard 8bit colour, synchronously and asynchronously, then compare the original with the newly saved images.
|
|
||||||
|
|
||||||
To run the tests, fetch the repo (tests are not distributed via npm) and install with `npm i`, run `npm test`.
|
|
||||||
|
|
||||||
The only thing not converted is gamma correction - this is because multiple vendors will do gamma correction differently, so the tests will have different results on different browsers.
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
$ npm install pngjs --save
|
|
||||||
```
|
|
||||||
|
|
||||||
# Browser
|
|
||||||
|
|
||||||
The package has been build with a [Browserify](browserify.org) version (`npm run browserify`) and you can use the browser version by including in your code:
|
|
||||||
|
|
||||||
```
|
|
||||||
import { PNG } from 'pngjs/browser';
|
|
||||||
```
|
|
||||||
|
|
||||||
# Example
|
|
||||||
|
|
||||||
```js
|
|
||||||
var fs = require("fs"),
|
|
||||||
PNG = require("pngjs").PNG;
|
|
||||||
|
|
||||||
fs.createReadStream("in.png")
|
|
||||||
.pipe(
|
|
||||||
new PNG({
|
|
||||||
filterType: 4,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.on("parsed", function () {
|
|
||||||
for (var y = 0; y < this.height; y++) {
|
|
||||||
for (var x = 0; x < this.width; x++) {
|
|
||||||
var idx = (this.width * y + x) << 2;
|
|
||||||
|
|
||||||
// invert color
|
|
||||||
this.data[idx] = 255 - this.data[idx];
|
|
||||||
this.data[idx + 1] = 255 - this.data[idx + 1];
|
|
||||||
this.data[idx + 2] = 255 - this.data[idx + 2];
|
|
||||||
|
|
||||||
// and reduce opacity
|
|
||||||
this.data[idx + 3] = this.data[idx + 3] >> 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.pack().pipe(fs.createWriteStream("out.png"));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
For more examples see `examples` folder.
|
|
||||||
|
|
||||||
# Async API
|
|
||||||
|
|
||||||
As input any color type is accepted (grayscale, rgb, palette, grayscale with alpha, rgb with alpha) but 8 bit per sample (channel) is the only supported bit depth. Interlaced mode is not supported.
|
|
||||||
|
|
||||||
## Class: PNG
|
|
||||||
|
|
||||||
`PNG` is readable and writable `Stream`.
|
|
||||||
|
|
||||||
### Options
|
|
||||||
|
|
||||||
- `width` - use this with `height` if you want to create png from scratch
|
|
||||||
- `height` - as above
|
|
||||||
- `checkCRC` - whether parser should be strict about checksums in source stream (default: `true`)
|
|
||||||
- `deflateChunkSize` - chunk size used for deflating data chunks, this should be power of 2 and must not be less than 256 and more than 32\*1024 (default: 32 kB)
|
|
||||||
- `deflateLevel` - compression level for deflate (default: 9)
|
|
||||||
- `deflateStrategy` - compression strategy for deflate (default: 3)
|
|
||||||
- `deflateFactory` - deflate stream factory (default: `zlib.createDeflate`)
|
|
||||||
- `filterType` - png filtering method for scanlines (default: -1 => auto, accepts array of numbers 0-4)
|
|
||||||
- `colorType` - the output colorType - see constants. 0 = grayscale, no alpha, 2 = color, no alpha, 4 = grayscale & alpha, 6 = color & alpha. Default currently 6, but in the future may calculate best mode.
|
|
||||||
- `inputColorType` - the input colorType - see constants. Default is 6 (RGBA)
|
|
||||||
- `bitDepth` - the bitDepth of the output, 8 or 16 bits. Input data is expected to have this bit depth.
|
|
||||||
16 bit data is expected in the system endianness (Default: 8)
|
|
||||||
- `inputHasAlpha` - whether the input bitmap has 4 bytes per pixel (rgb and alpha) or 3 (rgb - no alpha).
|
|
||||||
- `bgColor` - an object containing red, green, and blue values between 0 and 255
|
|
||||||
that is used when packing a PNG if alpha is not to be included (default: 255,255,255)
|
|
||||||
|
|
||||||
### Event "metadata"
|
|
||||||
|
|
||||||
`function(metadata) { }`
|
|
||||||
Image's header has been parsed, metadata contains this information:
|
|
||||||
|
|
||||||
- `width` image size in pixels
|
|
||||||
- `height` image size in pixels
|
|
||||||
- `palette` image is paletted
|
|
||||||
- `color` image is not grayscale
|
|
||||||
- `alpha` image contains alpha channel
|
|
||||||
- `interlace` image is interlaced
|
|
||||||
|
|
||||||
### Event: "parsed"
|
|
||||||
|
|
||||||
`function(data) { }`
|
|
||||||
Input image has been completely parsed, `data` is complete and ready for modification.
|
|
||||||
|
|
||||||
### Event: "error"
|
|
||||||
|
|
||||||
`function(error) { }`
|
|
||||||
|
|
||||||
### png.parse(data, [callback])
|
|
||||||
|
|
||||||
Parses PNG file data. Can be `String` or `Buffer`. Alternatively you can stream data to instance of PNG.
|
|
||||||
|
|
||||||
Optional `callback` is once called on `error` or `parsed`. The callback gets
|
|
||||||
two arguments `(err, data)`.
|
|
||||||
|
|
||||||
Returns `this` for method chaining.
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
|
||||||
```js
|
|
||||||
new PNG({ filterType: 4 }).parse(imageData, function (error, data) {
|
|
||||||
console.log(error, data);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### png.pack()
|
|
||||||
|
|
||||||
Starts converting data to PNG file Stream.
|
|
||||||
|
|
||||||
Returns `this` for method chaining.
|
|
||||||
|
|
||||||
### png.bitblt(dst, sx, sy, w, h, dx, dy)
|
|
||||||
|
|
||||||
Helper for image manipulation, copies a rectangle of pixels from current (i.e. the source) image (`sx`, `sy`, `w`, `h`) to `dst` image (at `dx`, `dy`).
|
|
||||||
|
|
||||||
Returns `this` for method chaining.
|
|
||||||
|
|
||||||
For example, the following code copies the top-left 100x50 px of `in.png` into dst and writes it to `out.png`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var dst = new PNG({ width: 100, height: 50 });
|
|
||||||
fs.createReadStream("in.png")
|
|
||||||
.pipe(new PNG())
|
|
||||||
.on("parsed", function () {
|
|
||||||
this.bitblt(dst, 0, 0, 100, 50, 0, 0);
|
|
||||||
dst.pack().pipe(fs.createWriteStream("out.png"));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Property: adjustGamma()
|
|
||||||
|
|
||||||
Helper that takes data and adjusts it to be gamma corrected. Note that it is not 100% reliable with transparent colours because that requires knowing the background colour the bitmap is rendered on to.
|
|
||||||
|
|
||||||
In tests against PNG suite it compared 100% with chrome on all 8 bit and below images. On IE there were some differences.
|
|
||||||
|
|
||||||
The following example reads a file, adjusts the gamma (which sets the gamma to 0) and writes it out again, effectively removing any gamma correction from the image.
|
|
||||||
|
|
||||||
```js
|
|
||||||
fs.createReadStream("in.png")
|
|
||||||
.pipe(new PNG())
|
|
||||||
.on("parsed", function () {
|
|
||||||
this.adjustGamma();
|
|
||||||
this.pack().pipe(fs.createWriteStream("out.png"));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Property: width
|
|
||||||
|
|
||||||
Width of image in pixels
|
|
||||||
|
|
||||||
### Property: height
|
|
||||||
|
|
||||||
Height of image in pixels
|
|
||||||
|
|
||||||
### Property: data
|
|
||||||
|
|
||||||
Buffer of image pixel data. Every pixel consists 4 bytes: R, G, B, A (opacity).
|
|
||||||
|
|
||||||
### Property: gamma
|
|
||||||
|
|
||||||
Gamma of image (0 if not specified)
|
|
||||||
|
|
||||||
## Packing a PNG and removing alpha (RGBA to RGB)
|
|
||||||
|
|
||||||
When removing the alpha channel from an image, there needs to be a background color to correctly
|
|
||||||
convert each pixel's transparency to the appropriate RGB value. By default, pngjs will flatten
|
|
||||||
the image against a white background. You can override this in the options:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var fs = require("fs"),
|
|
||||||
PNG = require("pngjs").PNG;
|
|
||||||
|
|
||||||
fs.createReadStream("in.png")
|
|
||||||
.pipe(
|
|
||||||
new PNG({
|
|
||||||
colorType: 2,
|
|
||||||
bgColor: {
|
|
||||||
red: 0,
|
|
||||||
green: 255,
|
|
||||||
blue: 0,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.on("parsed", function () {
|
|
||||||
this.pack().pipe(fs.createWriteStream("out.png"));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
# Sync API
|
|
||||||
|
|
||||||
## PNG.sync
|
|
||||||
|
|
||||||
### PNG.sync.read(buffer)
|
|
||||||
|
|
||||||
Take a buffer and returns a PNG image. The properties on the image include the meta data and `data` as per the async API above.
|
|
||||||
|
|
||||||
```
|
|
||||||
var data = fs.readFileSync('in.png');
|
|
||||||
var png = PNG.sync.read(data);
|
|
||||||
```
|
|
||||||
|
|
||||||
### PNG.sync.write(png)
|
|
||||||
|
|
||||||
Take a PNG image and returns a buffer. The properties on the image include the meta data and `data` as per the async API above.
|
|
||||||
|
|
||||||
```
|
|
||||||
var data = fs.readFileSync('in.png');
|
|
||||||
var png = PNG.sync.read(data);
|
|
||||||
var options = { colorType: 6 };
|
|
||||||
var buffer = PNG.sync.write(png, options);
|
|
||||||
fs.writeFileSync('out.png', buffer);
|
|
||||||
```
|
|
||||||
|
|
||||||
### PNG.adjustGamma(src)
|
|
||||||
|
|
||||||
Adjusts the gamma of a sync image. See the async adjustGamma.
|
|
||||||
|
|
||||||
```
|
|
||||||
var data = fs.readFileSync('in.png');
|
|
||||||
var png = PNG.sync.read(data);
|
|
||||||
PNG.adjustGamma(png);
|
|
||||||
```
|
|
||||||
18985
node_modules/pngjs/browser.js
generated
vendored
18985
node_modules/pngjs/browser.js
generated
vendored
File diff suppressed because it is too large
Load Diff
267
node_modules/pngjs/lib/bitmapper.js
generated
vendored
267
node_modules/pngjs/lib/bitmapper.js
generated
vendored
@ -1,267 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let interlaceUtils = require("./interlace");
|
|
||||||
|
|
||||||
let pixelBppMapper = [
|
|
||||||
// 0 - dummy entry
|
|
||||||
function () {},
|
|
||||||
|
|
||||||
// 1 - L
|
|
||||||
// 0: 0, 1: 0, 2: 0, 3: 0xff
|
|
||||||
function (pxData, data, pxPos, rawPos) {
|
|
||||||
if (rawPos === data.length) {
|
|
||||||
throw new Error("Ran out of data");
|
|
||||||
}
|
|
||||||
|
|
||||||
let pixel = data[rawPos];
|
|
||||||
pxData[pxPos] = pixel;
|
|
||||||
pxData[pxPos + 1] = pixel;
|
|
||||||
pxData[pxPos + 2] = pixel;
|
|
||||||
pxData[pxPos + 3] = 0xff;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 2 - LA
|
|
||||||
// 0: 0, 1: 0, 2: 0, 3: 1
|
|
||||||
function (pxData, data, pxPos, rawPos) {
|
|
||||||
if (rawPos + 1 >= data.length) {
|
|
||||||
throw new Error("Ran out of data");
|
|
||||||
}
|
|
||||||
|
|
||||||
let pixel = data[rawPos];
|
|
||||||
pxData[pxPos] = pixel;
|
|
||||||
pxData[pxPos + 1] = pixel;
|
|
||||||
pxData[pxPos + 2] = pixel;
|
|
||||||
pxData[pxPos + 3] = data[rawPos + 1];
|
|
||||||
},
|
|
||||||
|
|
||||||
// 3 - RGB
|
|
||||||
// 0: 0, 1: 1, 2: 2, 3: 0xff
|
|
||||||
function (pxData, data, pxPos, rawPos) {
|
|
||||||
if (rawPos + 2 >= data.length) {
|
|
||||||
throw new Error("Ran out of data");
|
|
||||||
}
|
|
||||||
|
|
||||||
pxData[pxPos] = data[rawPos];
|
|
||||||
pxData[pxPos + 1] = data[rawPos + 1];
|
|
||||||
pxData[pxPos + 2] = data[rawPos + 2];
|
|
||||||
pxData[pxPos + 3] = 0xff;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 4 - RGBA
|
|
||||||
// 0: 0, 1: 1, 2: 2, 3: 3
|
|
||||||
function (pxData, data, pxPos, rawPos) {
|
|
||||||
if (rawPos + 3 >= data.length) {
|
|
||||||
throw new Error("Ran out of data");
|
|
||||||
}
|
|
||||||
|
|
||||||
pxData[pxPos] = data[rawPos];
|
|
||||||
pxData[pxPos + 1] = data[rawPos + 1];
|
|
||||||
pxData[pxPos + 2] = data[rawPos + 2];
|
|
||||||
pxData[pxPos + 3] = data[rawPos + 3];
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let pixelBppCustomMapper = [
|
|
||||||
// 0 - dummy entry
|
|
||||||
function () {},
|
|
||||||
|
|
||||||
// 1 - L
|
|
||||||
// 0: 0, 1: 0, 2: 0, 3: 0xff
|
|
||||||
function (pxData, pixelData, pxPos, maxBit) {
|
|
||||||
let pixel = pixelData[0];
|
|
||||||
pxData[pxPos] = pixel;
|
|
||||||
pxData[pxPos + 1] = pixel;
|
|
||||||
pxData[pxPos + 2] = pixel;
|
|
||||||
pxData[pxPos + 3] = maxBit;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 2 - LA
|
|
||||||
// 0: 0, 1: 0, 2: 0, 3: 1
|
|
||||||
function (pxData, pixelData, pxPos) {
|
|
||||||
let pixel = pixelData[0];
|
|
||||||
pxData[pxPos] = pixel;
|
|
||||||
pxData[pxPos + 1] = pixel;
|
|
||||||
pxData[pxPos + 2] = pixel;
|
|
||||||
pxData[pxPos + 3] = pixelData[1];
|
|
||||||
},
|
|
||||||
|
|
||||||
// 3 - RGB
|
|
||||||
// 0: 0, 1: 1, 2: 2, 3: 0xff
|
|
||||||
function (pxData, pixelData, pxPos, maxBit) {
|
|
||||||
pxData[pxPos] = pixelData[0];
|
|
||||||
pxData[pxPos + 1] = pixelData[1];
|
|
||||||
pxData[pxPos + 2] = pixelData[2];
|
|
||||||
pxData[pxPos + 3] = maxBit;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 4 - RGBA
|
|
||||||
// 0: 0, 1: 1, 2: 2, 3: 3
|
|
||||||
function (pxData, pixelData, pxPos) {
|
|
||||||
pxData[pxPos] = pixelData[0];
|
|
||||||
pxData[pxPos + 1] = pixelData[1];
|
|
||||||
pxData[pxPos + 2] = pixelData[2];
|
|
||||||
pxData[pxPos + 3] = pixelData[3];
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function bitRetriever(data, depth) {
|
|
||||||
let leftOver = [];
|
|
||||||
let i = 0;
|
|
||||||
|
|
||||||
function split() {
|
|
||||||
if (i === data.length) {
|
|
||||||
throw new Error("Ran out of data");
|
|
||||||
}
|
|
||||||
let byte = data[i];
|
|
||||||
i++;
|
|
||||||
let byte8, byte7, byte6, byte5, byte4, byte3, byte2, byte1;
|
|
||||||
switch (depth) {
|
|
||||||
default:
|
|
||||||
throw new Error("unrecognised depth");
|
|
||||||
case 16:
|
|
||||||
byte2 = data[i];
|
|
||||||
i++;
|
|
||||||
leftOver.push((byte << 8) + byte2);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
byte2 = byte & 0x0f;
|
|
||||||
byte1 = byte >> 4;
|
|
||||||
leftOver.push(byte1, byte2);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
byte4 = byte & 3;
|
|
||||||
byte3 = (byte >> 2) & 3;
|
|
||||||
byte2 = (byte >> 4) & 3;
|
|
||||||
byte1 = (byte >> 6) & 3;
|
|
||||||
leftOver.push(byte1, byte2, byte3, byte4);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
byte8 = byte & 1;
|
|
||||||
byte7 = (byte >> 1) & 1;
|
|
||||||
byte6 = (byte >> 2) & 1;
|
|
||||||
byte5 = (byte >> 3) & 1;
|
|
||||||
byte4 = (byte >> 4) & 1;
|
|
||||||
byte3 = (byte >> 5) & 1;
|
|
||||||
byte2 = (byte >> 6) & 1;
|
|
||||||
byte1 = (byte >> 7) & 1;
|
|
||||||
leftOver.push(byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
get: function (count) {
|
|
||||||
while (leftOver.length < count) {
|
|
||||||
split();
|
|
||||||
}
|
|
||||||
let returner = leftOver.slice(0, count);
|
|
||||||
leftOver = leftOver.slice(count);
|
|
||||||
return returner;
|
|
||||||
},
|
|
||||||
resetAfterLine: function () {
|
|
||||||
leftOver.length = 0;
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
if (i !== data.length) {
|
|
||||||
throw new Error("extra data found");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapImage8Bit(image, pxData, getPxPos, bpp, data, rawPos) {
|
|
||||||
// eslint-disable-line max-params
|
|
||||||
let imageWidth = image.width;
|
|
||||||
let imageHeight = image.height;
|
|
||||||
let imagePass = image.index;
|
|
||||||
for (let y = 0; y < imageHeight; y++) {
|
|
||||||
for (let x = 0; x < imageWidth; x++) {
|
|
||||||
let pxPos = getPxPos(x, y, imagePass);
|
|
||||||
pixelBppMapper[bpp](pxData, data, pxPos, rawPos);
|
|
||||||
rawPos += bpp; //eslint-disable-line no-param-reassign
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rawPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapImageCustomBit(image, pxData, getPxPos, bpp, bits, maxBit) {
|
|
||||||
// eslint-disable-line max-params
|
|
||||||
let imageWidth = image.width;
|
|
||||||
let imageHeight = image.height;
|
|
||||||
let imagePass = image.index;
|
|
||||||
for (let y = 0; y < imageHeight; y++) {
|
|
||||||
for (let x = 0; x < imageWidth; x++) {
|
|
||||||
let pixelData = bits.get(bpp);
|
|
||||||
let pxPos = getPxPos(x, y, imagePass);
|
|
||||||
pixelBppCustomMapper[bpp](pxData, pixelData, pxPos, maxBit);
|
|
||||||
}
|
|
||||||
bits.resetAfterLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.dataToBitMap = function (data, bitmapInfo) {
|
|
||||||
let width = bitmapInfo.width;
|
|
||||||
let height = bitmapInfo.height;
|
|
||||||
let depth = bitmapInfo.depth;
|
|
||||||
let bpp = bitmapInfo.bpp;
|
|
||||||
let interlace = bitmapInfo.interlace;
|
|
||||||
let bits;
|
|
||||||
|
|
||||||
if (depth !== 8) {
|
|
||||||
bits = bitRetriever(data, depth);
|
|
||||||
}
|
|
||||||
let pxData;
|
|
||||||
if (depth <= 8) {
|
|
||||||
pxData = Buffer.alloc(width * height * 4);
|
|
||||||
} else {
|
|
||||||
pxData = new Uint16Array(width * height * 4);
|
|
||||||
}
|
|
||||||
let maxBit = Math.pow(2, depth) - 1;
|
|
||||||
let rawPos = 0;
|
|
||||||
let images;
|
|
||||||
let getPxPos;
|
|
||||||
|
|
||||||
if (interlace) {
|
|
||||||
images = interlaceUtils.getImagePasses(width, height);
|
|
||||||
getPxPos = interlaceUtils.getInterlaceIterator(width, height);
|
|
||||||
} else {
|
|
||||||
let nonInterlacedPxPos = 0;
|
|
||||||
getPxPos = function () {
|
|
||||||
let returner = nonInterlacedPxPos;
|
|
||||||
nonInterlacedPxPos += 4;
|
|
||||||
return returner;
|
|
||||||
};
|
|
||||||
images = [{ width: width, height: height }];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let imageIndex = 0; imageIndex < images.length; imageIndex++) {
|
|
||||||
if (depth === 8) {
|
|
||||||
rawPos = mapImage8Bit(
|
|
||||||
images[imageIndex],
|
|
||||||
pxData,
|
|
||||||
getPxPos,
|
|
||||||
bpp,
|
|
||||||
data,
|
|
||||||
rawPos
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
mapImageCustomBit(
|
|
||||||
images[imageIndex],
|
|
||||||
pxData,
|
|
||||||
getPxPos,
|
|
||||||
bpp,
|
|
||||||
bits,
|
|
||||||
maxBit
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (depth === 8) {
|
|
||||||
if (rawPos !== data.length) {
|
|
||||||
throw new Error("extra data found");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bits.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
return pxData;
|
|
||||||
};
|
|
||||||
158
node_modules/pngjs/lib/bitpacker.js
generated
vendored
158
node_modules/pngjs/lib/bitpacker.js
generated
vendored
@ -1,158 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let constants = require("./constants");
|
|
||||||
|
|
||||||
module.exports = function (dataIn, width, height, options) {
|
|
||||||
let outHasAlpha =
|
|
||||||
[constants.COLORTYPE_COLOR_ALPHA, constants.COLORTYPE_ALPHA].indexOf(
|
|
||||||
options.colorType
|
|
||||||
) !== -1;
|
|
||||||
if (options.colorType === options.inputColorType) {
|
|
||||||
let bigEndian = (function () {
|
|
||||||
let buffer = new ArrayBuffer(2);
|
|
||||||
new DataView(buffer).setInt16(0, 256, true /* littleEndian */);
|
|
||||||
// Int16Array uses the platform's endianness.
|
|
||||||
return new Int16Array(buffer)[0] !== 256;
|
|
||||||
})();
|
|
||||||
// If no need to convert to grayscale and alpha is present/absent in both, take a fast route
|
|
||||||
if (options.bitDepth === 8 || (options.bitDepth === 16 && bigEndian)) {
|
|
||||||
return dataIn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// map to a UInt16 array if data is 16bit, fix endianness below
|
|
||||||
let data = options.bitDepth !== 16 ? dataIn : new Uint16Array(dataIn.buffer);
|
|
||||||
|
|
||||||
let maxValue = 255;
|
|
||||||
let inBpp = constants.COLORTYPE_TO_BPP_MAP[options.inputColorType];
|
|
||||||
if (inBpp === 4 && !options.inputHasAlpha) {
|
|
||||||
inBpp = 3;
|
|
||||||
}
|
|
||||||
let outBpp = constants.COLORTYPE_TO_BPP_MAP[options.colorType];
|
|
||||||
if (options.bitDepth === 16) {
|
|
||||||
maxValue = 65535;
|
|
||||||
outBpp *= 2;
|
|
||||||
}
|
|
||||||
let outData = Buffer.alloc(width * height * outBpp);
|
|
||||||
|
|
||||||
let inIndex = 0;
|
|
||||||
let outIndex = 0;
|
|
||||||
|
|
||||||
let bgColor = options.bgColor || {};
|
|
||||||
if (bgColor.red === undefined) {
|
|
||||||
bgColor.red = maxValue;
|
|
||||||
}
|
|
||||||
if (bgColor.green === undefined) {
|
|
||||||
bgColor.green = maxValue;
|
|
||||||
}
|
|
||||||
if (bgColor.blue === undefined) {
|
|
||||||
bgColor.blue = maxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRGBA() {
|
|
||||||
let red;
|
|
||||||
let green;
|
|
||||||
let blue;
|
|
||||||
let alpha = maxValue;
|
|
||||||
switch (options.inputColorType) {
|
|
||||||
case constants.COLORTYPE_COLOR_ALPHA:
|
|
||||||
alpha = data[inIndex + 3];
|
|
||||||
red = data[inIndex];
|
|
||||||
green = data[inIndex + 1];
|
|
||||||
blue = data[inIndex + 2];
|
|
||||||
break;
|
|
||||||
case constants.COLORTYPE_COLOR:
|
|
||||||
red = data[inIndex];
|
|
||||||
green = data[inIndex + 1];
|
|
||||||
blue = data[inIndex + 2];
|
|
||||||
break;
|
|
||||||
case constants.COLORTYPE_ALPHA:
|
|
||||||
alpha = data[inIndex + 1];
|
|
||||||
red = data[inIndex];
|
|
||||||
green = red;
|
|
||||||
blue = red;
|
|
||||||
break;
|
|
||||||
case constants.COLORTYPE_GRAYSCALE:
|
|
||||||
red = data[inIndex];
|
|
||||||
green = red;
|
|
||||||
blue = red;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error(
|
|
||||||
"input color type:" +
|
|
||||||
options.inputColorType +
|
|
||||||
" is not supported at present"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.inputHasAlpha) {
|
|
||||||
if (!outHasAlpha) {
|
|
||||||
alpha /= maxValue;
|
|
||||||
red = Math.min(
|
|
||||||
Math.max(Math.round((1 - alpha) * bgColor.red + alpha * red), 0),
|
|
||||||
maxValue
|
|
||||||
);
|
|
||||||
green = Math.min(
|
|
||||||
Math.max(Math.round((1 - alpha) * bgColor.green + alpha * green), 0),
|
|
||||||
maxValue
|
|
||||||
);
|
|
||||||
blue = Math.min(
|
|
||||||
Math.max(Math.round((1 - alpha) * bgColor.blue + alpha * blue), 0),
|
|
||||||
maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { red: red, green: green, blue: blue, alpha: alpha };
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let y = 0; y < height; y++) {
|
|
||||||
for (let x = 0; x < width; x++) {
|
|
||||||
let rgba = getRGBA(data, inIndex);
|
|
||||||
|
|
||||||
switch (options.colorType) {
|
|
||||||
case constants.COLORTYPE_COLOR_ALPHA:
|
|
||||||
case constants.COLORTYPE_COLOR:
|
|
||||||
if (options.bitDepth === 8) {
|
|
||||||
outData[outIndex] = rgba.red;
|
|
||||||
outData[outIndex + 1] = rgba.green;
|
|
||||||
outData[outIndex + 2] = rgba.blue;
|
|
||||||
if (outHasAlpha) {
|
|
||||||
outData[outIndex + 3] = rgba.alpha;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
outData.writeUInt16BE(rgba.red, outIndex);
|
|
||||||
outData.writeUInt16BE(rgba.green, outIndex + 2);
|
|
||||||
outData.writeUInt16BE(rgba.blue, outIndex + 4);
|
|
||||||
if (outHasAlpha) {
|
|
||||||
outData.writeUInt16BE(rgba.alpha, outIndex + 6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case constants.COLORTYPE_ALPHA:
|
|
||||||
case constants.COLORTYPE_GRAYSCALE: {
|
|
||||||
// Convert to grayscale and alpha
|
|
||||||
let grayscale = (rgba.red + rgba.green + rgba.blue) / 3;
|
|
||||||
if (options.bitDepth === 8) {
|
|
||||||
outData[outIndex] = grayscale;
|
|
||||||
if (outHasAlpha) {
|
|
||||||
outData[outIndex + 1] = rgba.alpha;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
outData.writeUInt16BE(grayscale, outIndex);
|
|
||||||
if (outHasAlpha) {
|
|
||||||
outData.writeUInt16BE(rgba.alpha, outIndex + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new Error("unrecognised color Type " + options.colorType);
|
|
||||||
}
|
|
||||||
|
|
||||||
inIndex += inBpp;
|
|
||||||
outIndex += outBpp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return outData;
|
|
||||||
};
|
|
||||||
189
node_modules/pngjs/lib/chunkstream.js
generated
vendored
189
node_modules/pngjs/lib/chunkstream.js
generated
vendored
@ -1,189 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let util = require("util");
|
|
||||||
let Stream = require("stream");
|
|
||||||
|
|
||||||
let ChunkStream = (module.exports = function () {
|
|
||||||
Stream.call(this);
|
|
||||||
|
|
||||||
this._buffers = [];
|
|
||||||
this._buffered = 0;
|
|
||||||
|
|
||||||
this._reads = [];
|
|
||||||
this._paused = false;
|
|
||||||
|
|
||||||
this._encoding = "utf8";
|
|
||||||
this.writable = true;
|
|
||||||
});
|
|
||||||
util.inherits(ChunkStream, Stream);
|
|
||||||
|
|
||||||
ChunkStream.prototype.read = function (length, callback) {
|
|
||||||
this._reads.push({
|
|
||||||
length: Math.abs(length), // if length < 0 then at most this length
|
|
||||||
allowLess: length < 0,
|
|
||||||
func: callback,
|
|
||||||
});
|
|
||||||
|
|
||||||
process.nextTick(
|
|
||||||
function () {
|
|
||||||
this._process();
|
|
||||||
|
|
||||||
// its paused and there is not enought data then ask for more
|
|
||||||
if (this._paused && this._reads && this._reads.length > 0) {
|
|
||||||
this._paused = false;
|
|
||||||
|
|
||||||
this.emit("drain");
|
|
||||||
}
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkStream.prototype.write = function (data, encoding) {
|
|
||||||
if (!this.writable) {
|
|
||||||
this.emit("error", new Error("Stream not writable"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let dataBuffer;
|
|
||||||
if (Buffer.isBuffer(data)) {
|
|
||||||
dataBuffer = data;
|
|
||||||
} else {
|
|
||||||
dataBuffer = Buffer.from(data, encoding || this._encoding);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._buffers.push(dataBuffer);
|
|
||||||
this._buffered += dataBuffer.length;
|
|
||||||
|
|
||||||
this._process();
|
|
||||||
|
|
||||||
// ok if there are no more read requests
|
|
||||||
if (this._reads && this._reads.length === 0) {
|
|
||||||
this._paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.writable && !this._paused;
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkStream.prototype.end = function (data, encoding) {
|
|
||||||
if (data) {
|
|
||||||
this.write(data, encoding);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.writable = false;
|
|
||||||
|
|
||||||
// already destroyed
|
|
||||||
if (!this._buffers) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// enqueue or handle end
|
|
||||||
if (this._buffers.length === 0) {
|
|
||||||
this._end();
|
|
||||||
} else {
|
|
||||||
this._buffers.push(null);
|
|
||||||
this._process();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkStream.prototype.destroySoon = ChunkStream.prototype.end;
|
|
||||||
|
|
||||||
ChunkStream.prototype._end = function () {
|
|
||||||
if (this._reads.length > 0) {
|
|
||||||
this.emit("error", new Error("Unexpected end of input"));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.destroy();
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkStream.prototype.destroy = function () {
|
|
||||||
if (!this._buffers) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.writable = false;
|
|
||||||
this._reads = null;
|
|
||||||
this._buffers = null;
|
|
||||||
|
|
||||||
this.emit("close");
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkStream.prototype._processReadAllowingLess = function (read) {
|
|
||||||
// ok there is any data so that we can satisfy this request
|
|
||||||
this._reads.shift(); // == read
|
|
||||||
|
|
||||||
// first we need to peek into first buffer
|
|
||||||
let smallerBuf = this._buffers[0];
|
|
||||||
|
|
||||||
// ok there is more data than we need
|
|
||||||
if (smallerBuf.length > read.length) {
|
|
||||||
this._buffered -= read.length;
|
|
||||||
this._buffers[0] = smallerBuf.slice(read.length);
|
|
||||||
|
|
||||||
read.func.call(this, smallerBuf.slice(0, read.length));
|
|
||||||
} else {
|
|
||||||
// ok this is less than maximum length so use it all
|
|
||||||
this._buffered -= smallerBuf.length;
|
|
||||||
this._buffers.shift(); // == smallerBuf
|
|
||||||
|
|
||||||
read.func.call(this, smallerBuf);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkStream.prototype._processRead = function (read) {
|
|
||||||
this._reads.shift(); // == read
|
|
||||||
|
|
||||||
let pos = 0;
|
|
||||||
let count = 0;
|
|
||||||
let data = Buffer.alloc(read.length);
|
|
||||||
|
|
||||||
// create buffer for all data
|
|
||||||
while (pos < read.length) {
|
|
||||||
let buf = this._buffers[count++];
|
|
||||||
let len = Math.min(buf.length, read.length - pos);
|
|
||||||
|
|
||||||
buf.copy(data, pos, 0, len);
|
|
||||||
pos += len;
|
|
||||||
|
|
||||||
// last buffer wasn't used all so just slice it and leave
|
|
||||||
if (len !== buf.length) {
|
|
||||||
this._buffers[--count] = buf.slice(len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove all used buffers
|
|
||||||
if (count > 0) {
|
|
||||||
this._buffers.splice(0, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._buffered -= read.length;
|
|
||||||
|
|
||||||
read.func.call(this, data);
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkStream.prototype._process = function () {
|
|
||||||
try {
|
|
||||||
// as long as there is any data and read requests
|
|
||||||
while (this._buffered > 0 && this._reads && this._reads.length > 0) {
|
|
||||||
let read = this._reads[0];
|
|
||||||
|
|
||||||
// read any data (but no more than length)
|
|
||||||
if (read.allowLess) {
|
|
||||||
this._processReadAllowingLess(read);
|
|
||||||
} else if (this._buffered >= read.length) {
|
|
||||||
// ok we can meet some expectations
|
|
||||||
|
|
||||||
this._processRead(read);
|
|
||||||
} else {
|
|
||||||
// not enought data to satisfy first request in queue
|
|
||||||
// so we need to wait for more
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._buffers && !this.writable) {
|
|
||||||
this._end();
|
|
||||||
}
|
|
||||||
} catch (ex) {
|
|
||||||
this.emit("error", ex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
32
node_modules/pngjs/lib/constants.js
generated
vendored
32
node_modules/pngjs/lib/constants.js
generated
vendored
@ -1,32 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
PNG_SIGNATURE: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a],
|
|
||||||
|
|
||||||
TYPE_IHDR: 0x49484452,
|
|
||||||
TYPE_IEND: 0x49454e44,
|
|
||||||
TYPE_IDAT: 0x49444154,
|
|
||||||
TYPE_PLTE: 0x504c5445,
|
|
||||||
TYPE_tRNS: 0x74524e53, // eslint-disable-line camelcase
|
|
||||||
TYPE_gAMA: 0x67414d41, // eslint-disable-line camelcase
|
|
||||||
|
|
||||||
// color-type bits
|
|
||||||
COLORTYPE_GRAYSCALE: 0,
|
|
||||||
COLORTYPE_PALETTE: 1,
|
|
||||||
COLORTYPE_COLOR: 2,
|
|
||||||
COLORTYPE_ALPHA: 4, // e.g. grayscale and alpha
|
|
||||||
|
|
||||||
// color-type combinations
|
|
||||||
COLORTYPE_PALETTE_COLOR: 3,
|
|
||||||
COLORTYPE_COLOR_ALPHA: 6,
|
|
||||||
|
|
||||||
COLORTYPE_TO_BPP_MAP: {
|
|
||||||
0: 1,
|
|
||||||
2: 3,
|
|
||||||
3: 1,
|
|
||||||
4: 2,
|
|
||||||
6: 4,
|
|
||||||
},
|
|
||||||
|
|
||||||
GAMMA_DIVISION: 100000,
|
|
||||||
};
|
|
||||||
40
node_modules/pngjs/lib/crc.js
generated
vendored
40
node_modules/pngjs/lib/crc.js
generated
vendored
@ -1,40 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let crcTable = [];
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
for (let i = 0; i < 256; i++) {
|
|
||||||
let currentCrc = i;
|
|
||||||
for (let j = 0; j < 8; j++) {
|
|
||||||
if (currentCrc & 1) {
|
|
||||||
currentCrc = 0xedb88320 ^ (currentCrc >>> 1);
|
|
||||||
} else {
|
|
||||||
currentCrc = currentCrc >>> 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
crcTable[i] = currentCrc;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
let CrcCalculator = (module.exports = function () {
|
|
||||||
this._crc = -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
CrcCalculator.prototype.write = function (data) {
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
this._crc = crcTable[(this._crc ^ data[i]) & 0xff] ^ (this._crc >>> 8);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
CrcCalculator.prototype.crc32 = function () {
|
|
||||||
return this._crc ^ -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
CrcCalculator.crc32 = function (buf) {
|
|
||||||
let crc = -1;
|
|
||||||
for (let i = 0; i < buf.length; i++) {
|
|
||||||
crc = crcTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
|
|
||||||
}
|
|
||||||
return crc ^ -1;
|
|
||||||
};
|
|
||||||
171
node_modules/pngjs/lib/filter-pack.js
generated
vendored
171
node_modules/pngjs/lib/filter-pack.js
generated
vendored
@ -1,171 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let paethPredictor = require("./paeth-predictor");
|
|
||||||
|
|
||||||
function filterNone(pxData, pxPos, byteWidth, rawData, rawPos) {
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
rawData[rawPos + x] = pxData[pxPos + x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterSumNone(pxData, pxPos, byteWidth) {
|
|
||||||
let sum = 0;
|
|
||||||
let length = pxPos + byteWidth;
|
|
||||||
|
|
||||||
for (let i = pxPos; i < length; i++) {
|
|
||||||
sum += Math.abs(pxData[i]);
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterSub(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
||||||
let val = pxData[pxPos + x] - left;
|
|
||||||
|
|
||||||
rawData[rawPos + x] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterSumSub(pxData, pxPos, byteWidth, bpp) {
|
|
||||||
let sum = 0;
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
||||||
let val = pxData[pxPos + x] - left;
|
|
||||||
|
|
||||||
sum += Math.abs(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterUp(pxData, pxPos, byteWidth, rawData, rawPos) {
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
||||||
let val = pxData[pxPos + x] - up;
|
|
||||||
|
|
||||||
rawData[rawPos + x] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterSumUp(pxData, pxPos, byteWidth) {
|
|
||||||
let sum = 0;
|
|
||||||
let length = pxPos + byteWidth;
|
|
||||||
for (let x = pxPos; x < length; x++) {
|
|
||||||
let up = pxPos > 0 ? pxData[x - byteWidth] : 0;
|
|
||||||
let val = pxData[x] - up;
|
|
||||||
|
|
||||||
sum += Math.abs(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterAvg(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
||||||
let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
||||||
let val = pxData[pxPos + x] - ((left + up) >> 1);
|
|
||||||
|
|
||||||
rawData[rawPos + x] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterSumAvg(pxData, pxPos, byteWidth, bpp) {
|
|
||||||
let sum = 0;
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
||||||
let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
||||||
let val = pxData[pxPos + x] - ((left + up) >> 1);
|
|
||||||
|
|
||||||
sum += Math.abs(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterPaeth(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
||||||
let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
||||||
let upleft =
|
|
||||||
pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
|
|
||||||
let val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
|
|
||||||
|
|
||||||
rawData[rawPos + x] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterSumPaeth(pxData, pxPos, byteWidth, bpp) {
|
|
||||||
let sum = 0;
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
||||||
let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
||||||
let upleft =
|
|
||||||
pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
|
|
||||||
let val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
|
|
||||||
|
|
||||||
sum += Math.abs(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
let filters = {
|
|
||||||
0: filterNone,
|
|
||||||
1: filterSub,
|
|
||||||
2: filterUp,
|
|
||||||
3: filterAvg,
|
|
||||||
4: filterPaeth,
|
|
||||||
};
|
|
||||||
|
|
||||||
let filterSums = {
|
|
||||||
0: filterSumNone,
|
|
||||||
1: filterSumSub,
|
|
||||||
2: filterSumUp,
|
|
||||||
3: filterSumAvg,
|
|
||||||
4: filterSumPaeth,
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = function (pxData, width, height, options, bpp) {
|
|
||||||
let filterTypes;
|
|
||||||
if (!("filterType" in options) || options.filterType === -1) {
|
|
||||||
filterTypes = [0, 1, 2, 3, 4];
|
|
||||||
} else if (typeof options.filterType === "number") {
|
|
||||||
filterTypes = [options.filterType];
|
|
||||||
} else {
|
|
||||||
throw new Error("unrecognised filter types");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.bitDepth === 16) {
|
|
||||||
bpp *= 2;
|
|
||||||
}
|
|
||||||
let byteWidth = width * bpp;
|
|
||||||
let rawPos = 0;
|
|
||||||
let pxPos = 0;
|
|
||||||
let rawData = Buffer.alloc((byteWidth + 1) * height);
|
|
||||||
|
|
||||||
let sel = filterTypes[0];
|
|
||||||
|
|
||||||
for (let y = 0; y < height; y++) {
|
|
||||||
if (filterTypes.length > 1) {
|
|
||||||
// find best filter for this line (with lowest sum of values)
|
|
||||||
let min = Infinity;
|
|
||||||
|
|
||||||
for (let i = 0; i < filterTypes.length; i++) {
|
|
||||||
let sum = filterSums[filterTypes[i]](pxData, pxPos, byteWidth, bpp);
|
|
||||||
if (sum < min) {
|
|
||||||
sel = filterTypes[i];
|
|
||||||
min = sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rawData[rawPos] = sel;
|
|
||||||
rawPos++;
|
|
||||||
filters[sel](pxData, pxPos, byteWidth, rawData, rawPos, bpp);
|
|
||||||
rawPos += byteWidth;
|
|
||||||
pxPos += byteWidth;
|
|
||||||
}
|
|
||||||
return rawData;
|
|
||||||
};
|
|
||||||
24
node_modules/pngjs/lib/filter-parse-async.js
generated
vendored
24
node_modules/pngjs/lib/filter-parse-async.js
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let util = require("util");
|
|
||||||
let ChunkStream = require("./chunkstream");
|
|
||||||
let Filter = require("./filter-parse");
|
|
||||||
|
|
||||||
let FilterAsync = (module.exports = function (bitmapInfo) {
|
|
||||||
ChunkStream.call(this);
|
|
||||||
|
|
||||||
let buffers = [];
|
|
||||||
let that = this;
|
|
||||||
this._filter = new Filter(bitmapInfo, {
|
|
||||||
read: this.read.bind(this),
|
|
||||||
write: function (buffer) {
|
|
||||||
buffers.push(buffer);
|
|
||||||
},
|
|
||||||
complete: function () {
|
|
||||||
that.emit("complete", Buffer.concat(buffers));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this._filter.start();
|
|
||||||
});
|
|
||||||
util.inherits(FilterAsync, ChunkStream);
|
|
||||||
21
node_modules/pngjs/lib/filter-parse-sync.js
generated
vendored
21
node_modules/pngjs/lib/filter-parse-sync.js
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let SyncReader = require("./sync-reader");
|
|
||||||
let Filter = require("./filter-parse");
|
|
||||||
|
|
||||||
exports.process = function (inBuffer, bitmapInfo) {
|
|
||||||
let outBuffers = [];
|
|
||||||
let reader = new SyncReader(inBuffer);
|
|
||||||
let filter = new Filter(bitmapInfo, {
|
|
||||||
read: reader.read.bind(reader),
|
|
||||||
write: function (bufferPart) {
|
|
||||||
outBuffers.push(bufferPart);
|
|
||||||
},
|
|
||||||
complete: function () {},
|
|
||||||
});
|
|
||||||
|
|
||||||
filter.start();
|
|
||||||
reader.process();
|
|
||||||
|
|
||||||
return Buffer.concat(outBuffers);
|
|
||||||
};
|
|
||||||
177
node_modules/pngjs/lib/filter-parse.js
generated
vendored
177
node_modules/pngjs/lib/filter-parse.js
generated
vendored
@ -1,177 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let interlaceUtils = require("./interlace");
|
|
||||||
let paethPredictor = require("./paeth-predictor");
|
|
||||||
|
|
||||||
function getByteWidth(width, bpp, depth) {
|
|
||||||
let byteWidth = width * bpp;
|
|
||||||
if (depth !== 8) {
|
|
||||||
byteWidth = Math.ceil(byteWidth / (8 / depth));
|
|
||||||
}
|
|
||||||
return byteWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
let Filter = (module.exports = function (bitmapInfo, dependencies) {
|
|
||||||
let width = bitmapInfo.width;
|
|
||||||
let height = bitmapInfo.height;
|
|
||||||
let interlace = bitmapInfo.interlace;
|
|
||||||
let bpp = bitmapInfo.bpp;
|
|
||||||
let depth = bitmapInfo.depth;
|
|
||||||
|
|
||||||
this.read = dependencies.read;
|
|
||||||
this.write = dependencies.write;
|
|
||||||
this.complete = dependencies.complete;
|
|
||||||
|
|
||||||
this._imageIndex = 0;
|
|
||||||
this._images = [];
|
|
||||||
if (interlace) {
|
|
||||||
let passes = interlaceUtils.getImagePasses(width, height);
|
|
||||||
for (let i = 0; i < passes.length; i++) {
|
|
||||||
this._images.push({
|
|
||||||
byteWidth: getByteWidth(passes[i].width, bpp, depth),
|
|
||||||
height: passes[i].height,
|
|
||||||
lineIndex: 0,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._images.push({
|
|
||||||
byteWidth: getByteWidth(width, bpp, depth),
|
|
||||||
height: height,
|
|
||||||
lineIndex: 0,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// when filtering the line we look at the pixel to the left
|
|
||||||
// the spec also says it is done on a byte level regardless of the number of pixels
|
|
||||||
// so if the depth is byte compatible (8 or 16) we subtract the bpp in order to compare back
|
|
||||||
// a pixel rather than just a different byte part. However if we are sub byte, we ignore.
|
|
||||||
if (depth === 8) {
|
|
||||||
this._xComparison = bpp;
|
|
||||||
} else if (depth === 16) {
|
|
||||||
this._xComparison = bpp * 2;
|
|
||||||
} else {
|
|
||||||
this._xComparison = 1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Filter.prototype.start = function () {
|
|
||||||
this.read(
|
|
||||||
this._images[this._imageIndex].byteWidth + 1,
|
|
||||||
this._reverseFilterLine.bind(this)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Filter.prototype._unFilterType1 = function (
|
|
||||||
rawData,
|
|
||||||
unfilteredLine,
|
|
||||||
byteWidth
|
|
||||||
) {
|
|
||||||
let xComparison = this._xComparison;
|
|
||||||
let xBiggerThan = xComparison - 1;
|
|
||||||
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let rawByte = rawData[1 + x];
|
|
||||||
let f1Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
|
|
||||||
unfilteredLine[x] = rawByte + f1Left;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Filter.prototype._unFilterType2 = function (
|
|
||||||
rawData,
|
|
||||||
unfilteredLine,
|
|
||||||
byteWidth
|
|
||||||
) {
|
|
||||||
let lastLine = this._lastLine;
|
|
||||||
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let rawByte = rawData[1 + x];
|
|
||||||
let f2Up = lastLine ? lastLine[x] : 0;
|
|
||||||
unfilteredLine[x] = rawByte + f2Up;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Filter.prototype._unFilterType3 = function (
|
|
||||||
rawData,
|
|
||||||
unfilteredLine,
|
|
||||||
byteWidth
|
|
||||||
) {
|
|
||||||
let xComparison = this._xComparison;
|
|
||||||
let xBiggerThan = xComparison - 1;
|
|
||||||
let lastLine = this._lastLine;
|
|
||||||
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let rawByte = rawData[1 + x];
|
|
||||||
let f3Up = lastLine ? lastLine[x] : 0;
|
|
||||||
let f3Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
|
|
||||||
let f3Add = Math.floor((f3Left + f3Up) / 2);
|
|
||||||
unfilteredLine[x] = rawByte + f3Add;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Filter.prototype._unFilterType4 = function (
|
|
||||||
rawData,
|
|
||||||
unfilteredLine,
|
|
||||||
byteWidth
|
|
||||||
) {
|
|
||||||
let xComparison = this._xComparison;
|
|
||||||
let xBiggerThan = xComparison - 1;
|
|
||||||
let lastLine = this._lastLine;
|
|
||||||
|
|
||||||
for (let x = 0; x < byteWidth; x++) {
|
|
||||||
let rawByte = rawData[1 + x];
|
|
||||||
let f4Up = lastLine ? lastLine[x] : 0;
|
|
||||||
let f4Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
|
|
||||||
let f4UpLeft = x > xBiggerThan && lastLine ? lastLine[x - xComparison] : 0;
|
|
||||||
let f4Add = paethPredictor(f4Left, f4Up, f4UpLeft);
|
|
||||||
unfilteredLine[x] = rawByte + f4Add;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Filter.prototype._reverseFilterLine = function (rawData) {
|
|
||||||
let filter = rawData[0];
|
|
||||||
let unfilteredLine;
|
|
||||||
let currentImage = this._images[this._imageIndex];
|
|
||||||
let byteWidth = currentImage.byteWidth;
|
|
||||||
|
|
||||||
if (filter === 0) {
|
|
||||||
unfilteredLine = rawData.slice(1, byteWidth + 1);
|
|
||||||
} else {
|
|
||||||
unfilteredLine = Buffer.alloc(byteWidth);
|
|
||||||
|
|
||||||
switch (filter) {
|
|
||||||
case 1:
|
|
||||||
this._unFilterType1(rawData, unfilteredLine, byteWidth);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
this._unFilterType2(rawData, unfilteredLine, byteWidth);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
this._unFilterType3(rawData, unfilteredLine, byteWidth);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
this._unFilterType4(rawData, unfilteredLine, byteWidth);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error("Unrecognised filter type - " + filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.write(unfilteredLine);
|
|
||||||
|
|
||||||
currentImage.lineIndex++;
|
|
||||||
if (currentImage.lineIndex >= currentImage.height) {
|
|
||||||
this._lastLine = null;
|
|
||||||
this._imageIndex++;
|
|
||||||
currentImage = this._images[this._imageIndex];
|
|
||||||
} else {
|
|
||||||
this._lastLine = unfilteredLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentImage) {
|
|
||||||
// read, using the byte width that may be from the new current image
|
|
||||||
this.read(currentImage.byteWidth + 1, this._reverseFilterLine.bind(this));
|
|
||||||
} else {
|
|
||||||
this._lastLine = null;
|
|
||||||
this.complete();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
93
node_modules/pngjs/lib/format-normaliser.js
generated
vendored
93
node_modules/pngjs/lib/format-normaliser.js
generated
vendored
@ -1,93 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
function dePalette(indata, outdata, width, height, palette) {
|
|
||||||
let pxPos = 0;
|
|
||||||
// use values from palette
|
|
||||||
for (let y = 0; y < height; y++) {
|
|
||||||
for (let x = 0; x < width; x++) {
|
|
||||||
let color = palette[indata[pxPos]];
|
|
||||||
|
|
||||||
if (!color) {
|
|
||||||
throw new Error("index " + indata[pxPos] + " not in palette");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < 4; i++) {
|
|
||||||
outdata[pxPos + i] = color[i];
|
|
||||||
}
|
|
||||||
pxPos += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceTransparentColor(indata, outdata, width, height, transColor) {
|
|
||||||
let pxPos = 0;
|
|
||||||
for (let y = 0; y < height; y++) {
|
|
||||||
for (let x = 0; x < width; x++) {
|
|
||||||
let makeTrans = false;
|
|
||||||
|
|
||||||
if (transColor.length === 1) {
|
|
||||||
if (transColor[0] === indata[pxPos]) {
|
|
||||||
makeTrans = true;
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
transColor[0] === indata[pxPos] &&
|
|
||||||
transColor[1] === indata[pxPos + 1] &&
|
|
||||||
transColor[2] === indata[pxPos + 2]
|
|
||||||
) {
|
|
||||||
makeTrans = true;
|
|
||||||
}
|
|
||||||
if (makeTrans) {
|
|
||||||
for (let i = 0; i < 4; i++) {
|
|
||||||
outdata[pxPos + i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pxPos += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function scaleDepth(indata, outdata, width, height, depth) {
|
|
||||||
let maxOutSample = 255;
|
|
||||||
let maxInSample = Math.pow(2, depth) - 1;
|
|
||||||
let pxPos = 0;
|
|
||||||
|
|
||||||
for (let y = 0; y < height; y++) {
|
|
||||||
for (let x = 0; x < width; x++) {
|
|
||||||
for (let i = 0; i < 4; i++) {
|
|
||||||
outdata[pxPos + i] = Math.floor(
|
|
||||||
(indata[pxPos + i] * maxOutSample) / maxInSample + 0.5
|
|
||||||
);
|
|
||||||
}
|
|
||||||
pxPos += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function (indata, imageData, skipRescale = false) {
|
|
||||||
let depth = imageData.depth;
|
|
||||||
let width = imageData.width;
|
|
||||||
let height = imageData.height;
|
|
||||||
let colorType = imageData.colorType;
|
|
||||||
let transColor = imageData.transColor;
|
|
||||||
let palette = imageData.palette;
|
|
||||||
|
|
||||||
let outdata = indata; // only different for 16 bits
|
|
||||||
|
|
||||||
if (colorType === 3) {
|
|
||||||
// paletted
|
|
||||||
dePalette(indata, outdata, width, height, palette);
|
|
||||||
} else {
|
|
||||||
if (transColor) {
|
|
||||||
replaceTransparentColor(indata, outdata, width, height, transColor);
|
|
||||||
}
|
|
||||||
// if it needs scaling
|
|
||||||
if (depth !== 8 && !skipRescale) {
|
|
||||||
// if we need to change the buffer size
|
|
||||||
if (depth === 16) {
|
|
||||||
outdata = Buffer.alloc(width * height * 4);
|
|
||||||
}
|
|
||||||
scaleDepth(indata, outdata, width, height, depth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return outdata;
|
|
||||||
};
|
|
||||||
95
node_modules/pngjs/lib/interlace.js
generated
vendored
95
node_modules/pngjs/lib/interlace.js
generated
vendored
@ -1,95 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
// Adam 7
|
|
||||||
// 0 1 2 3 4 5 6 7
|
|
||||||
// 0 x 6 4 6 x 6 4 6
|
|
||||||
// 1 7 7 7 7 7 7 7 7
|
|
||||||
// 2 5 6 5 6 5 6 5 6
|
|
||||||
// 3 7 7 7 7 7 7 7 7
|
|
||||||
// 4 3 6 4 6 3 6 4 6
|
|
||||||
// 5 7 7 7 7 7 7 7 7
|
|
||||||
// 6 5 6 5 6 5 6 5 6
|
|
||||||
// 7 7 7 7 7 7 7 7 7
|
|
||||||
|
|
||||||
let imagePasses = [
|
|
||||||
{
|
|
||||||
// pass 1 - 1px
|
|
||||||
x: [0],
|
|
||||||
y: [0],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// pass 2 - 1px
|
|
||||||
x: [4],
|
|
||||||
y: [0],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// pass 3 - 2px
|
|
||||||
x: [0, 4],
|
|
||||||
y: [4],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// pass 4 - 4px
|
|
||||||
x: [2, 6],
|
|
||||||
y: [0, 4],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// pass 5 - 8px
|
|
||||||
x: [0, 2, 4, 6],
|
|
||||||
y: [2, 6],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// pass 6 - 16px
|
|
||||||
x: [1, 3, 5, 7],
|
|
||||||
y: [0, 2, 4, 6],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// pass 7 - 32px
|
|
||||||
x: [0, 1, 2, 3, 4, 5, 6, 7],
|
|
||||||
y: [1, 3, 5, 7],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
exports.getImagePasses = function (width, height) {
|
|
||||||
let images = [];
|
|
||||||
let xLeftOver = width % 8;
|
|
||||||
let yLeftOver = height % 8;
|
|
||||||
let xRepeats = (width - xLeftOver) / 8;
|
|
||||||
let yRepeats = (height - yLeftOver) / 8;
|
|
||||||
for (let i = 0; i < imagePasses.length; i++) {
|
|
||||||
let pass = imagePasses[i];
|
|
||||||
let passWidth = xRepeats * pass.x.length;
|
|
||||||
let passHeight = yRepeats * pass.y.length;
|
|
||||||
for (let j = 0; j < pass.x.length; j++) {
|
|
||||||
if (pass.x[j] < xLeftOver) {
|
|
||||||
passWidth++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let j = 0; j < pass.y.length; j++) {
|
|
||||||
if (pass.y[j] < yLeftOver) {
|
|
||||||
passHeight++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (passWidth > 0 && passHeight > 0) {
|
|
||||||
images.push({ width: passWidth, height: passHeight, index: i });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return images;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.getInterlaceIterator = function (width) {
|
|
||||||
return function (x, y, pass) {
|
|
||||||
let outerXLeftOver = x % imagePasses[pass].x.length;
|
|
||||||
let outerX =
|
|
||||||
((x - outerXLeftOver) / imagePasses[pass].x.length) * 8 +
|
|
||||||
imagePasses[pass].x[outerXLeftOver];
|
|
||||||
let outerYLeftOver = y % imagePasses[pass].y.length;
|
|
||||||
let outerY =
|
|
||||||
((y - outerYLeftOver) / imagePasses[pass].y.length) * 8 +
|
|
||||||
imagePasses[pass].y[outerYLeftOver];
|
|
||||||
return outerX * 4 + outerY * width * 4;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
50
node_modules/pngjs/lib/packer-async.js
generated
vendored
50
node_modules/pngjs/lib/packer-async.js
generated
vendored
@ -1,50 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let util = require("util");
|
|
||||||
let Stream = require("stream");
|
|
||||||
let constants = require("./constants");
|
|
||||||
let Packer = require("./packer");
|
|
||||||
|
|
||||||
let PackerAsync = (module.exports = function (opt) {
|
|
||||||
Stream.call(this);
|
|
||||||
|
|
||||||
let options = opt || {};
|
|
||||||
|
|
||||||
this._packer = new Packer(options);
|
|
||||||
this._deflate = this._packer.createDeflate();
|
|
||||||
|
|
||||||
this.readable = true;
|
|
||||||
});
|
|
||||||
util.inherits(PackerAsync, Stream);
|
|
||||||
|
|
||||||
PackerAsync.prototype.pack = function (data, width, height, gamma) {
|
|
||||||
// Signature
|
|
||||||
this.emit("data", Buffer.from(constants.PNG_SIGNATURE));
|
|
||||||
this.emit("data", this._packer.packIHDR(width, height));
|
|
||||||
|
|
||||||
if (gamma) {
|
|
||||||
this.emit("data", this._packer.packGAMA(gamma));
|
|
||||||
}
|
|
||||||
|
|
||||||
let filteredData = this._packer.filterData(data, width, height);
|
|
||||||
|
|
||||||
// compress it
|
|
||||||
this._deflate.on("error", this.emit.bind(this, "error"));
|
|
||||||
|
|
||||||
this._deflate.on(
|
|
||||||
"data",
|
|
||||||
function (compressedData) {
|
|
||||||
this.emit("data", this._packer.packIDAT(compressedData));
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
|
|
||||||
this._deflate.on(
|
|
||||||
"end",
|
|
||||||
function () {
|
|
||||||
this.emit("data", this._packer.packIEND());
|
|
||||||
this.emit("end");
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
|
|
||||||
this._deflate.end(filteredData);
|
|
||||||
};
|
|
||||||
56
node_modules/pngjs/lib/packer-sync.js
generated
vendored
56
node_modules/pngjs/lib/packer-sync.js
generated
vendored
@ -1,56 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let hasSyncZlib = true;
|
|
||||||
let zlib = require("zlib");
|
|
||||||
if (!zlib.deflateSync) {
|
|
||||||
hasSyncZlib = false;
|
|
||||||
}
|
|
||||||
let constants = require("./constants");
|
|
||||||
let Packer = require("./packer");
|
|
||||||
|
|
||||||
module.exports = function (metaData, opt) {
|
|
||||||
if (!hasSyncZlib) {
|
|
||||||
throw new Error(
|
|
||||||
"To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let options = opt || {};
|
|
||||||
|
|
||||||
let packer = new Packer(options);
|
|
||||||
|
|
||||||
let chunks = [];
|
|
||||||
|
|
||||||
// Signature
|
|
||||||
chunks.push(Buffer.from(constants.PNG_SIGNATURE));
|
|
||||||
|
|
||||||
// Header
|
|
||||||
chunks.push(packer.packIHDR(metaData.width, metaData.height));
|
|
||||||
|
|
||||||
if (metaData.gamma) {
|
|
||||||
chunks.push(packer.packGAMA(metaData.gamma));
|
|
||||||
}
|
|
||||||
|
|
||||||
let filteredData = packer.filterData(
|
|
||||||
metaData.data,
|
|
||||||
metaData.width,
|
|
||||||
metaData.height
|
|
||||||
);
|
|
||||||
|
|
||||||
// compress it
|
|
||||||
let compressedData = zlib.deflateSync(
|
|
||||||
filteredData,
|
|
||||||
packer.getDeflateOptions()
|
|
||||||
);
|
|
||||||
filteredData = null;
|
|
||||||
|
|
||||||
if (!compressedData || !compressedData.length) {
|
|
||||||
throw new Error("bad png - invalid compressed data response");
|
|
||||||
}
|
|
||||||
chunks.push(packer.packIDAT(compressedData));
|
|
||||||
|
|
||||||
// End
|
|
||||||
chunks.push(packer.packIEND());
|
|
||||||
|
|
||||||
return Buffer.concat(chunks);
|
|
||||||
};
|
|
||||||
129
node_modules/pngjs/lib/packer.js
generated
vendored
129
node_modules/pngjs/lib/packer.js
generated
vendored
@ -1,129 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let constants = require("./constants");
|
|
||||||
let CrcStream = require("./crc");
|
|
||||||
let bitPacker = require("./bitpacker");
|
|
||||||
let filter = require("./filter-pack");
|
|
||||||
let zlib = require("zlib");
|
|
||||||
|
|
||||||
let Packer = (module.exports = function (options) {
|
|
||||||
this._options = options;
|
|
||||||
|
|
||||||
options.deflateChunkSize = options.deflateChunkSize || 32 * 1024;
|
|
||||||
options.deflateLevel =
|
|
||||||
options.deflateLevel != null ? options.deflateLevel : 9;
|
|
||||||
options.deflateStrategy =
|
|
||||||
options.deflateStrategy != null ? options.deflateStrategy : 3;
|
|
||||||
options.inputHasAlpha =
|
|
||||||
options.inputHasAlpha != null ? options.inputHasAlpha : true;
|
|
||||||
options.deflateFactory = options.deflateFactory || zlib.createDeflate;
|
|
||||||
options.bitDepth = options.bitDepth || 8;
|
|
||||||
// This is outputColorType
|
|
||||||
options.colorType =
|
|
||||||
typeof options.colorType === "number"
|
|
||||||
? options.colorType
|
|
||||||
: constants.COLORTYPE_COLOR_ALPHA;
|
|
||||||
options.inputColorType =
|
|
||||||
typeof options.inputColorType === "number"
|
|
||||||
? options.inputColorType
|
|
||||||
: constants.COLORTYPE_COLOR_ALPHA;
|
|
||||||
|
|
||||||
if (
|
|
||||||
[
|
|
||||||
constants.COLORTYPE_GRAYSCALE,
|
|
||||||
constants.COLORTYPE_COLOR,
|
|
||||||
constants.COLORTYPE_COLOR_ALPHA,
|
|
||||||
constants.COLORTYPE_ALPHA,
|
|
||||||
].indexOf(options.colorType) === -1
|
|
||||||
) {
|
|
||||||
throw new Error(
|
|
||||||
"option color type:" + options.colorType + " is not supported at present"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
[
|
|
||||||
constants.COLORTYPE_GRAYSCALE,
|
|
||||||
constants.COLORTYPE_COLOR,
|
|
||||||
constants.COLORTYPE_COLOR_ALPHA,
|
|
||||||
constants.COLORTYPE_ALPHA,
|
|
||||||
].indexOf(options.inputColorType) === -1
|
|
||||||
) {
|
|
||||||
throw new Error(
|
|
||||||
"option input color type:" +
|
|
||||||
options.inputColorType +
|
|
||||||
" is not supported at present"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (options.bitDepth !== 8 && options.bitDepth !== 16) {
|
|
||||||
throw new Error(
|
|
||||||
"option bit depth:" + options.bitDepth + " is not supported at present"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Packer.prototype.getDeflateOptions = function () {
|
|
||||||
return {
|
|
||||||
chunkSize: this._options.deflateChunkSize,
|
|
||||||
level: this._options.deflateLevel,
|
|
||||||
strategy: this._options.deflateStrategy,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Packer.prototype.createDeflate = function () {
|
|
||||||
return this._options.deflateFactory(this.getDeflateOptions());
|
|
||||||
};
|
|
||||||
|
|
||||||
Packer.prototype.filterData = function (data, width, height) {
|
|
||||||
// convert to correct format for filtering (e.g. right bpp and bit depth)
|
|
||||||
let packedData = bitPacker(data, width, height, this._options);
|
|
||||||
|
|
||||||
// filter pixel data
|
|
||||||
let bpp = constants.COLORTYPE_TO_BPP_MAP[this._options.colorType];
|
|
||||||
let filteredData = filter(packedData, width, height, this._options, bpp);
|
|
||||||
return filteredData;
|
|
||||||
};
|
|
||||||
|
|
||||||
Packer.prototype._packChunk = function (type, data) {
|
|
||||||
let len = data ? data.length : 0;
|
|
||||||
let buf = Buffer.alloc(len + 12);
|
|
||||||
|
|
||||||
buf.writeUInt32BE(len, 0);
|
|
||||||
buf.writeUInt32BE(type, 4);
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
data.copy(buf, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.writeInt32BE(
|
|
||||||
CrcStream.crc32(buf.slice(4, buf.length - 4)),
|
|
||||||
buf.length - 4
|
|
||||||
);
|
|
||||||
return buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
Packer.prototype.packGAMA = function (gamma) {
|
|
||||||
let buf = Buffer.alloc(4);
|
|
||||||
buf.writeUInt32BE(Math.floor(gamma * constants.GAMMA_DIVISION), 0);
|
|
||||||
return this._packChunk(constants.TYPE_gAMA, buf);
|
|
||||||
};
|
|
||||||
|
|
||||||
Packer.prototype.packIHDR = function (width, height) {
|
|
||||||
let buf = Buffer.alloc(13);
|
|
||||||
buf.writeUInt32BE(width, 0);
|
|
||||||
buf.writeUInt32BE(height, 4);
|
|
||||||
buf[8] = this._options.bitDepth; // Bit depth
|
|
||||||
buf[9] = this._options.colorType; // colorType
|
|
||||||
buf[10] = 0; // compression
|
|
||||||
buf[11] = 0; // filter
|
|
||||||
buf[12] = 0; // interlace
|
|
||||||
|
|
||||||
return this._packChunk(constants.TYPE_IHDR, buf);
|
|
||||||
};
|
|
||||||
|
|
||||||
Packer.prototype.packIDAT = function (data) {
|
|
||||||
return this._packChunk(constants.TYPE_IDAT, data);
|
|
||||||
};
|
|
||||||
|
|
||||||
Packer.prototype.packIEND = function () {
|
|
||||||
return this._packChunk(constants.TYPE_IEND, null);
|
|
||||||
};
|
|
||||||
16
node_modules/pngjs/lib/paeth-predictor.js
generated
vendored
16
node_modules/pngjs/lib/paeth-predictor.js
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
module.exports = function paethPredictor(left, above, upLeft) {
|
|
||||||
let paeth = left + above - upLeft;
|
|
||||||
let pLeft = Math.abs(paeth - left);
|
|
||||||
let pAbove = Math.abs(paeth - above);
|
|
||||||
let pUpLeft = Math.abs(paeth - upLeft);
|
|
||||||
|
|
||||||
if (pLeft <= pAbove && pLeft <= pUpLeft) {
|
|
||||||
return left;
|
|
||||||
}
|
|
||||||
if (pAbove <= pUpLeft) {
|
|
||||||
return above;
|
|
||||||
}
|
|
||||||
return upLeft;
|
|
||||||
};
|
|
||||||
169
node_modules/pngjs/lib/parser-async.js
generated
vendored
169
node_modules/pngjs/lib/parser-async.js
generated
vendored
@ -1,169 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let util = require("util");
|
|
||||||
let zlib = require("zlib");
|
|
||||||
let ChunkStream = require("./chunkstream");
|
|
||||||
let FilterAsync = require("./filter-parse-async");
|
|
||||||
let Parser = require("./parser");
|
|
||||||
let bitmapper = require("./bitmapper");
|
|
||||||
let formatNormaliser = require("./format-normaliser");
|
|
||||||
|
|
||||||
let ParserAsync = (module.exports = function (options) {
|
|
||||||
ChunkStream.call(this);
|
|
||||||
|
|
||||||
this._parser = new Parser(options, {
|
|
||||||
read: this.read.bind(this),
|
|
||||||
error: this._handleError.bind(this),
|
|
||||||
metadata: this._handleMetaData.bind(this),
|
|
||||||
gamma: this.emit.bind(this, "gamma"),
|
|
||||||
palette: this._handlePalette.bind(this),
|
|
||||||
transColor: this._handleTransColor.bind(this),
|
|
||||||
finished: this._finished.bind(this),
|
|
||||||
inflateData: this._inflateData.bind(this),
|
|
||||||
simpleTransparency: this._simpleTransparency.bind(this),
|
|
||||||
headersFinished: this._headersFinished.bind(this),
|
|
||||||
});
|
|
||||||
this._options = options;
|
|
||||||
this.writable = true;
|
|
||||||
|
|
||||||
this._parser.start();
|
|
||||||
});
|
|
||||||
util.inherits(ParserAsync, ChunkStream);
|
|
||||||
|
|
||||||
ParserAsync.prototype._handleError = function (err) {
|
|
||||||
this.emit("error", err);
|
|
||||||
|
|
||||||
this.writable = false;
|
|
||||||
|
|
||||||
this.destroy();
|
|
||||||
|
|
||||||
if (this._inflate && this._inflate.destroy) {
|
|
||||||
this._inflate.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._filter) {
|
|
||||||
this._filter.destroy();
|
|
||||||
// For backward compatibility with Node 7 and below.
|
|
||||||
// Suppress errors due to _inflate calling write() even after
|
|
||||||
// it's destroy()'ed.
|
|
||||||
this._filter.on("error", function () {});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.errord = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
ParserAsync.prototype._inflateData = function (data) {
|
|
||||||
if (!this._inflate) {
|
|
||||||
if (this._bitmapInfo.interlace) {
|
|
||||||
this._inflate = zlib.createInflate();
|
|
||||||
|
|
||||||
this._inflate.on("error", this.emit.bind(this, "error"));
|
|
||||||
this._filter.on("complete", this._complete.bind(this));
|
|
||||||
|
|
||||||
this._inflate.pipe(this._filter);
|
|
||||||
} else {
|
|
||||||
let rowSize =
|
|
||||||
((this._bitmapInfo.width *
|
|
||||||
this._bitmapInfo.bpp *
|
|
||||||
this._bitmapInfo.depth +
|
|
||||||
7) >>
|
|
||||||
3) +
|
|
||||||
1;
|
|
||||||
let imageSize = rowSize * this._bitmapInfo.height;
|
|
||||||
let chunkSize = Math.max(imageSize, zlib.Z_MIN_CHUNK);
|
|
||||||
|
|
||||||
this._inflate = zlib.createInflate({ chunkSize: chunkSize });
|
|
||||||
let leftToInflate = imageSize;
|
|
||||||
|
|
||||||
let emitError = this.emit.bind(this, "error");
|
|
||||||
this._inflate.on("error", function (err) {
|
|
||||||
if (!leftToInflate) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emitError(err);
|
|
||||||
});
|
|
||||||
this._filter.on("complete", this._complete.bind(this));
|
|
||||||
|
|
||||||
let filterWrite = this._filter.write.bind(this._filter);
|
|
||||||
this._inflate.on("data", function (chunk) {
|
|
||||||
if (!leftToInflate) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chunk.length > leftToInflate) {
|
|
||||||
chunk = chunk.slice(0, leftToInflate);
|
|
||||||
}
|
|
||||||
|
|
||||||
leftToInflate -= chunk.length;
|
|
||||||
|
|
||||||
filterWrite(chunk);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._inflate.on("end", this._filter.end.bind(this._filter));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._inflate.write(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
ParserAsync.prototype._handleMetaData = function (metaData) {
|
|
||||||
this._metaData = metaData;
|
|
||||||
this._bitmapInfo = Object.create(metaData);
|
|
||||||
|
|
||||||
this._filter = new FilterAsync(this._bitmapInfo);
|
|
||||||
};
|
|
||||||
|
|
||||||
ParserAsync.prototype._handleTransColor = function (transColor) {
|
|
||||||
this._bitmapInfo.transColor = transColor;
|
|
||||||
};
|
|
||||||
|
|
||||||
ParserAsync.prototype._handlePalette = function (palette) {
|
|
||||||
this._bitmapInfo.palette = palette;
|
|
||||||
};
|
|
||||||
|
|
||||||
ParserAsync.prototype._simpleTransparency = function () {
|
|
||||||
this._metaData.alpha = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
ParserAsync.prototype._headersFinished = function () {
|
|
||||||
// Up until this point, we don't know if we have a tRNS chunk (alpha)
|
|
||||||
// so we can't emit metadata any earlier
|
|
||||||
this.emit("metadata", this._metaData);
|
|
||||||
};
|
|
||||||
|
|
||||||
ParserAsync.prototype._finished = function () {
|
|
||||||
if (this.errord) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._inflate) {
|
|
||||||
this.emit("error", "No Inflate block");
|
|
||||||
} else {
|
|
||||||
// no more data to inflate
|
|
||||||
this._inflate.end();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ParserAsync.prototype._complete = function (filteredData) {
|
|
||||||
if (this.errord) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let normalisedBitmapData;
|
|
||||||
|
|
||||||
try {
|
|
||||||
let bitmapData = bitmapper.dataToBitMap(filteredData, this._bitmapInfo);
|
|
||||||
|
|
||||||
normalisedBitmapData = formatNormaliser(
|
|
||||||
bitmapData,
|
|
||||||
this._bitmapInfo,
|
|
||||||
this._options.skipRescale
|
|
||||||
);
|
|
||||||
bitmapData = null;
|
|
||||||
} catch (ex) {
|
|
||||||
this._handleError(ex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.emit("parsed", normalisedBitmapData);
|
|
||||||
};
|
|
||||||
112
node_modules/pngjs/lib/parser-sync.js
generated
vendored
112
node_modules/pngjs/lib/parser-sync.js
generated
vendored
@ -1,112 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let hasSyncZlib = true;
|
|
||||||
let zlib = require("zlib");
|
|
||||||
let inflateSync = require("./sync-inflate");
|
|
||||||
if (!zlib.deflateSync) {
|
|
||||||
hasSyncZlib = false;
|
|
||||||
}
|
|
||||||
let SyncReader = require("./sync-reader");
|
|
||||||
let FilterSync = require("./filter-parse-sync");
|
|
||||||
let Parser = require("./parser");
|
|
||||||
let bitmapper = require("./bitmapper");
|
|
||||||
let formatNormaliser = require("./format-normaliser");
|
|
||||||
|
|
||||||
module.exports = function (buffer, options) {
|
|
||||||
if (!hasSyncZlib) {
|
|
||||||
throw new Error(
|
|
||||||
"To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let err;
|
|
||||||
function handleError(_err_) {
|
|
||||||
err = _err_;
|
|
||||||
}
|
|
||||||
|
|
||||||
let metaData;
|
|
||||||
function handleMetaData(_metaData_) {
|
|
||||||
metaData = _metaData_;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTransColor(transColor) {
|
|
||||||
metaData.transColor = transColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handlePalette(palette) {
|
|
||||||
metaData.palette = palette;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSimpleTransparency() {
|
|
||||||
metaData.alpha = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let gamma;
|
|
||||||
function handleGamma(_gamma_) {
|
|
||||||
gamma = _gamma_;
|
|
||||||
}
|
|
||||||
|
|
||||||
let inflateDataList = [];
|
|
||||||
function handleInflateData(inflatedData) {
|
|
||||||
inflateDataList.push(inflatedData);
|
|
||||||
}
|
|
||||||
|
|
||||||
let reader = new SyncReader(buffer);
|
|
||||||
|
|
||||||
let parser = new Parser(options, {
|
|
||||||
read: reader.read.bind(reader),
|
|
||||||
error: handleError,
|
|
||||||
metadata: handleMetaData,
|
|
||||||
gamma: handleGamma,
|
|
||||||
palette: handlePalette,
|
|
||||||
transColor: handleTransColor,
|
|
||||||
inflateData: handleInflateData,
|
|
||||||
simpleTransparency: handleSimpleTransparency,
|
|
||||||
});
|
|
||||||
|
|
||||||
parser.start();
|
|
||||||
reader.process();
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
//join together the inflate datas
|
|
||||||
let inflateData = Buffer.concat(inflateDataList);
|
|
||||||
inflateDataList.length = 0;
|
|
||||||
|
|
||||||
let inflatedData;
|
|
||||||
if (metaData.interlace) {
|
|
||||||
inflatedData = zlib.inflateSync(inflateData);
|
|
||||||
} else {
|
|
||||||
let rowSize =
|
|
||||||
((metaData.width * metaData.bpp * metaData.depth + 7) >> 3) + 1;
|
|
||||||
let imageSize = rowSize * metaData.height;
|
|
||||||
inflatedData = inflateSync(inflateData, {
|
|
||||||
chunkSize: imageSize,
|
|
||||||
maxLength: imageSize,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
inflateData = null;
|
|
||||||
|
|
||||||
if (!inflatedData || !inflatedData.length) {
|
|
||||||
throw new Error("bad png - invalid inflate data response");
|
|
||||||
}
|
|
||||||
|
|
||||||
let unfilteredData = FilterSync.process(inflatedData, metaData);
|
|
||||||
inflateData = null;
|
|
||||||
|
|
||||||
let bitmapData = bitmapper.dataToBitMap(unfilteredData, metaData);
|
|
||||||
unfilteredData = null;
|
|
||||||
|
|
||||||
let normalisedBitmapData = formatNormaliser(
|
|
||||||
bitmapData,
|
|
||||||
metaData,
|
|
||||||
options.skipRescale
|
|
||||||
);
|
|
||||||
|
|
||||||
metaData.data = normalisedBitmapData;
|
|
||||||
metaData.gamma = gamma || 0;
|
|
||||||
|
|
||||||
return metaData;
|
|
||||||
};
|
|
||||||
290
node_modules/pngjs/lib/parser.js
generated
vendored
290
node_modules/pngjs/lib/parser.js
generated
vendored
@ -1,290 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let constants = require("./constants");
|
|
||||||
let CrcCalculator = require("./crc");
|
|
||||||
|
|
||||||
let Parser = (module.exports = function (options, dependencies) {
|
|
||||||
this._options = options;
|
|
||||||
options.checkCRC = options.checkCRC !== false;
|
|
||||||
|
|
||||||
this._hasIHDR = false;
|
|
||||||
this._hasIEND = false;
|
|
||||||
this._emittedHeadersFinished = false;
|
|
||||||
|
|
||||||
// input flags/metadata
|
|
||||||
this._palette = [];
|
|
||||||
this._colorType = 0;
|
|
||||||
|
|
||||||
this._chunks = {};
|
|
||||||
this._chunks[constants.TYPE_IHDR] = this._handleIHDR.bind(this);
|
|
||||||
this._chunks[constants.TYPE_IEND] = this._handleIEND.bind(this);
|
|
||||||
this._chunks[constants.TYPE_IDAT] = this._handleIDAT.bind(this);
|
|
||||||
this._chunks[constants.TYPE_PLTE] = this._handlePLTE.bind(this);
|
|
||||||
this._chunks[constants.TYPE_tRNS] = this._handleTRNS.bind(this);
|
|
||||||
this._chunks[constants.TYPE_gAMA] = this._handleGAMA.bind(this);
|
|
||||||
|
|
||||||
this.read = dependencies.read;
|
|
||||||
this.error = dependencies.error;
|
|
||||||
this.metadata = dependencies.metadata;
|
|
||||||
this.gamma = dependencies.gamma;
|
|
||||||
this.transColor = dependencies.transColor;
|
|
||||||
this.palette = dependencies.palette;
|
|
||||||
this.parsed = dependencies.parsed;
|
|
||||||
this.inflateData = dependencies.inflateData;
|
|
||||||
this.finished = dependencies.finished;
|
|
||||||
this.simpleTransparency = dependencies.simpleTransparency;
|
|
||||||
this.headersFinished = dependencies.headersFinished || function () {};
|
|
||||||
});
|
|
||||||
|
|
||||||
Parser.prototype.start = function () {
|
|
||||||
this.read(constants.PNG_SIGNATURE.length, this._parseSignature.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._parseSignature = function (data) {
|
|
||||||
let signature = constants.PNG_SIGNATURE;
|
|
||||||
|
|
||||||
for (let i = 0; i < signature.length; i++) {
|
|
||||||
if (data[i] !== signature[i]) {
|
|
||||||
this.error(new Error("Invalid file signature"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.read(8, this._parseChunkBegin.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._parseChunkBegin = function (data) {
|
|
||||||
// chunk content length
|
|
||||||
let length = data.readUInt32BE(0);
|
|
||||||
|
|
||||||
// chunk type
|
|
||||||
let type = data.readUInt32BE(4);
|
|
||||||
let name = "";
|
|
||||||
for (let i = 4; i < 8; i++) {
|
|
||||||
name += String.fromCharCode(data[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.log('chunk ', name, length);
|
|
||||||
|
|
||||||
// chunk flags
|
|
||||||
let ancillary = Boolean(data[4] & 0x20); // or critical
|
|
||||||
// priv = Boolean(data[5] & 0x20), // or public
|
|
||||||
// safeToCopy = Boolean(data[7] & 0x20); // or unsafe
|
|
||||||
|
|
||||||
if (!this._hasIHDR && type !== constants.TYPE_IHDR) {
|
|
||||||
this.error(new Error("Expected IHDR on beggining"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._crc = new CrcCalculator();
|
|
||||||
this._crc.write(Buffer.from(name));
|
|
||||||
|
|
||||||
if (this._chunks[type]) {
|
|
||||||
return this._chunks[type](length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ancillary) {
|
|
||||||
this.error(new Error("Unsupported critical chunk type " + name));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.read(length + 4, this._skipChunk.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._skipChunk = function (/*data*/) {
|
|
||||||
this.read(8, this._parseChunkBegin.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._handleChunkEnd = function () {
|
|
||||||
this.read(4, this._parseChunkEnd.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._parseChunkEnd = function (data) {
|
|
||||||
let fileCrc = data.readInt32BE(0);
|
|
||||||
let calcCrc = this._crc.crc32();
|
|
||||||
|
|
||||||
// check CRC
|
|
||||||
if (this._options.checkCRC && calcCrc !== fileCrc) {
|
|
||||||
this.error(new Error("Crc error - " + fileCrc + " - " + calcCrc));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._hasIEND) {
|
|
||||||
this.read(8, this._parseChunkBegin.bind(this));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._handleIHDR = function (length) {
|
|
||||||
this.read(length, this._parseIHDR.bind(this));
|
|
||||||
};
|
|
||||||
Parser.prototype._parseIHDR = function (data) {
|
|
||||||
this._crc.write(data);
|
|
||||||
|
|
||||||
let width = data.readUInt32BE(0);
|
|
||||||
let height = data.readUInt32BE(4);
|
|
||||||
let depth = data[8];
|
|
||||||
let colorType = data[9]; // bits: 1 palette, 2 color, 4 alpha
|
|
||||||
let compr = data[10];
|
|
||||||
let filter = data[11];
|
|
||||||
let interlace = data[12];
|
|
||||||
|
|
||||||
// console.log(' width', width, 'height', height,
|
|
||||||
// 'depth', depth, 'colorType', colorType,
|
|
||||||
// 'compr', compr, 'filter', filter, 'interlace', interlace
|
|
||||||
// );
|
|
||||||
|
|
||||||
if (
|
|
||||||
depth !== 8 &&
|
|
||||||
depth !== 4 &&
|
|
||||||
depth !== 2 &&
|
|
||||||
depth !== 1 &&
|
|
||||||
depth !== 16
|
|
||||||
) {
|
|
||||||
this.error(new Error("Unsupported bit depth " + depth));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(colorType in constants.COLORTYPE_TO_BPP_MAP)) {
|
|
||||||
this.error(new Error("Unsupported color type"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (compr !== 0) {
|
|
||||||
this.error(new Error("Unsupported compression method"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (filter !== 0) {
|
|
||||||
this.error(new Error("Unsupported filter method"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (interlace !== 0 && interlace !== 1) {
|
|
||||||
this.error(new Error("Unsupported interlace method"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._colorType = colorType;
|
|
||||||
|
|
||||||
let bpp = constants.COLORTYPE_TO_BPP_MAP[this._colorType];
|
|
||||||
|
|
||||||
this._hasIHDR = true;
|
|
||||||
|
|
||||||
this.metadata({
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
depth: depth,
|
|
||||||
interlace: Boolean(interlace),
|
|
||||||
palette: Boolean(colorType & constants.COLORTYPE_PALETTE),
|
|
||||||
color: Boolean(colorType & constants.COLORTYPE_COLOR),
|
|
||||||
alpha: Boolean(colorType & constants.COLORTYPE_ALPHA),
|
|
||||||
bpp: bpp,
|
|
||||||
colorType: colorType,
|
|
||||||
});
|
|
||||||
|
|
||||||
this._handleChunkEnd();
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._handlePLTE = function (length) {
|
|
||||||
this.read(length, this._parsePLTE.bind(this));
|
|
||||||
};
|
|
||||||
Parser.prototype._parsePLTE = function (data) {
|
|
||||||
this._crc.write(data);
|
|
||||||
|
|
||||||
let entries = Math.floor(data.length / 3);
|
|
||||||
// console.log('Palette:', entries);
|
|
||||||
|
|
||||||
for (let i = 0; i < entries; i++) {
|
|
||||||
this._palette.push([data[i * 3], data[i * 3 + 1], data[i * 3 + 2], 0xff]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.palette(this._palette);
|
|
||||||
|
|
||||||
this._handleChunkEnd();
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._handleTRNS = function (length) {
|
|
||||||
this.simpleTransparency();
|
|
||||||
this.read(length, this._parseTRNS.bind(this));
|
|
||||||
};
|
|
||||||
Parser.prototype._parseTRNS = function (data) {
|
|
||||||
this._crc.write(data);
|
|
||||||
|
|
||||||
// palette
|
|
||||||
if (this._colorType === constants.COLORTYPE_PALETTE_COLOR) {
|
|
||||||
if (this._palette.length === 0) {
|
|
||||||
this.error(new Error("Transparency chunk must be after palette"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data.length > this._palette.length) {
|
|
||||||
this.error(new Error("More transparent colors than palette size"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
this._palette[i][3] = data[i];
|
|
||||||
}
|
|
||||||
this.palette(this._palette);
|
|
||||||
}
|
|
||||||
|
|
||||||
// for colorType 0 (grayscale) and 2 (rgb)
|
|
||||||
// there might be one gray/color defined as transparent
|
|
||||||
if (this._colorType === constants.COLORTYPE_GRAYSCALE) {
|
|
||||||
// grey, 2 bytes
|
|
||||||
this.transColor([data.readUInt16BE(0)]);
|
|
||||||
}
|
|
||||||
if (this._colorType === constants.COLORTYPE_COLOR) {
|
|
||||||
this.transColor([
|
|
||||||
data.readUInt16BE(0),
|
|
||||||
data.readUInt16BE(2),
|
|
||||||
data.readUInt16BE(4),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._handleChunkEnd();
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._handleGAMA = function (length) {
|
|
||||||
this.read(length, this._parseGAMA.bind(this));
|
|
||||||
};
|
|
||||||
Parser.prototype._parseGAMA = function (data) {
|
|
||||||
this._crc.write(data);
|
|
||||||
this.gamma(data.readUInt32BE(0) / constants.GAMMA_DIVISION);
|
|
||||||
|
|
||||||
this._handleChunkEnd();
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._handleIDAT = function (length) {
|
|
||||||
if (!this._emittedHeadersFinished) {
|
|
||||||
this._emittedHeadersFinished = true;
|
|
||||||
this.headersFinished();
|
|
||||||
}
|
|
||||||
this.read(-length, this._parseIDAT.bind(this, length));
|
|
||||||
};
|
|
||||||
Parser.prototype._parseIDAT = function (length, data) {
|
|
||||||
this._crc.write(data);
|
|
||||||
|
|
||||||
if (
|
|
||||||
this._colorType === constants.COLORTYPE_PALETTE_COLOR &&
|
|
||||||
this._palette.length === 0
|
|
||||||
) {
|
|
||||||
throw new Error("Expected palette not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.inflateData(data);
|
|
||||||
let leftOverLength = length - data.length;
|
|
||||||
|
|
||||||
if (leftOverLength > 0) {
|
|
||||||
this._handleIDAT(leftOverLength);
|
|
||||||
} else {
|
|
||||||
this._handleChunkEnd();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype._handleIEND = function (length) {
|
|
||||||
this.read(length, this._parseIEND.bind(this));
|
|
||||||
};
|
|
||||||
Parser.prototype._parseIEND = function (data) {
|
|
||||||
this._crc.write(data);
|
|
||||||
|
|
||||||
this._hasIEND = true;
|
|
||||||
this._handleChunkEnd();
|
|
||||||
|
|
||||||
if (this.finished) {
|
|
||||||
this.finished();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
12
node_modules/pngjs/lib/png-sync.js
generated
vendored
12
node_modules/pngjs/lib/png-sync.js
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let parse = require("./parser-sync");
|
|
||||||
let pack = require("./packer-sync");
|
|
||||||
|
|
||||||
exports.read = function (buffer, options) {
|
|
||||||
return parse(buffer, options || {});
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.write = function (png, options) {
|
|
||||||
return pack(png, options);
|
|
||||||
};
|
|
||||||
194
node_modules/pngjs/lib/png.js
generated
vendored
194
node_modules/pngjs/lib/png.js
generated
vendored
@ -1,194 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let util = require("util");
|
|
||||||
let Stream = require("stream");
|
|
||||||
let Parser = require("./parser-async");
|
|
||||||
let Packer = require("./packer-async");
|
|
||||||
let PNGSync = require("./png-sync");
|
|
||||||
|
|
||||||
let PNG = (exports.PNG = function (options) {
|
|
||||||
Stream.call(this);
|
|
||||||
|
|
||||||
options = options || {}; // eslint-disable-line no-param-reassign
|
|
||||||
|
|
||||||
// coerce pixel dimensions to integers (also coerces undefined -> 0):
|
|
||||||
this.width = options.width | 0;
|
|
||||||
this.height = options.height | 0;
|
|
||||||
|
|
||||||
this.data =
|
|
||||||
this.width > 0 && this.height > 0
|
|
||||||
? Buffer.alloc(4 * this.width * this.height)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (options.fill && this.data) {
|
|
||||||
this.data.fill(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.gamma = 0;
|
|
||||||
this.readable = this.writable = true;
|
|
||||||
|
|
||||||
this._parser = new Parser(options);
|
|
||||||
|
|
||||||
this._parser.on("error", this.emit.bind(this, "error"));
|
|
||||||
this._parser.on("close", this._handleClose.bind(this));
|
|
||||||
this._parser.on("metadata", this._metadata.bind(this));
|
|
||||||
this._parser.on("gamma", this._gamma.bind(this));
|
|
||||||
this._parser.on(
|
|
||||||
"parsed",
|
|
||||||
function (data) {
|
|
||||||
this.data = data;
|
|
||||||
this.emit("parsed", data);
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
|
|
||||||
this._packer = new Packer(options);
|
|
||||||
this._packer.on("data", this.emit.bind(this, "data"));
|
|
||||||
this._packer.on("end", this.emit.bind(this, "end"));
|
|
||||||
this._parser.on("close", this._handleClose.bind(this));
|
|
||||||
this._packer.on("error", this.emit.bind(this, "error"));
|
|
||||||
});
|
|
||||||
util.inherits(PNG, Stream);
|
|
||||||
|
|
||||||
PNG.sync = PNGSync;
|
|
||||||
|
|
||||||
PNG.prototype.pack = function () {
|
|
||||||
if (!this.data || !this.data.length) {
|
|
||||||
this.emit("error", "No data provided");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
process.nextTick(
|
|
||||||
function () {
|
|
||||||
this._packer.pack(this.data, this.width, this.height, this.gamma);
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.prototype.parse = function (data, callback) {
|
|
||||||
if (callback) {
|
|
||||||
let onParsed, onError;
|
|
||||||
|
|
||||||
onParsed = function (parsedData) {
|
|
||||||
this.removeListener("error", onError);
|
|
||||||
|
|
||||||
this.data = parsedData;
|
|
||||||
callback(null, this);
|
|
||||||
}.bind(this);
|
|
||||||
|
|
||||||
onError = function (err) {
|
|
||||||
this.removeListener("parsed", onParsed);
|
|
||||||
|
|
||||||
callback(err, null);
|
|
||||||
}.bind(this);
|
|
||||||
|
|
||||||
this.once("parsed", onParsed);
|
|
||||||
this.once("error", onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.end(data);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.prototype.write = function (data) {
|
|
||||||
this._parser.write(data);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.prototype.end = function (data) {
|
|
||||||
this._parser.end(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.prototype._metadata = function (metadata) {
|
|
||||||
this.width = metadata.width;
|
|
||||||
this.height = metadata.height;
|
|
||||||
|
|
||||||
this.emit("metadata", metadata);
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.prototype._gamma = function (gamma) {
|
|
||||||
this.gamma = gamma;
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.prototype._handleClose = function () {
|
|
||||||
if (!this._parser.writable && !this._packer.readable) {
|
|
||||||
this.emit("close");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.bitblt = function (src, dst, srcX, srcY, width, height, deltaX, deltaY) {
|
|
||||||
// eslint-disable-line max-params
|
|
||||||
// coerce pixel dimensions to integers (also coerces undefined -> 0):
|
|
||||||
/* eslint-disable no-param-reassign */
|
|
||||||
srcX |= 0;
|
|
||||||
srcY |= 0;
|
|
||||||
width |= 0;
|
|
||||||
height |= 0;
|
|
||||||
deltaX |= 0;
|
|
||||||
deltaY |= 0;
|
|
||||||
/* eslint-enable no-param-reassign */
|
|
||||||
|
|
||||||
if (
|
|
||||||
srcX > src.width ||
|
|
||||||
srcY > src.height ||
|
|
||||||
srcX + width > src.width ||
|
|
||||||
srcY + height > src.height
|
|
||||||
) {
|
|
||||||
throw new Error("bitblt reading outside image");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
deltaX > dst.width ||
|
|
||||||
deltaY > dst.height ||
|
|
||||||
deltaX + width > dst.width ||
|
|
||||||
deltaY + height > dst.height
|
|
||||||
) {
|
|
||||||
throw new Error("bitblt writing outside image");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let y = 0; y < height; y++) {
|
|
||||||
src.data.copy(
|
|
||||||
dst.data,
|
|
||||||
((deltaY + y) * dst.width + deltaX) << 2,
|
|
||||||
((srcY + y) * src.width + srcX) << 2,
|
|
||||||
((srcY + y) * src.width + srcX + width) << 2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.prototype.bitblt = function (
|
|
||||||
dst,
|
|
||||||
srcX,
|
|
||||||
srcY,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
deltaX,
|
|
||||||
deltaY
|
|
||||||
) {
|
|
||||||
// eslint-disable-line max-params
|
|
||||||
|
|
||||||
PNG.bitblt(this, dst, srcX, srcY, width, height, deltaX, deltaY);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.adjustGamma = function (src) {
|
|
||||||
if (src.gamma) {
|
|
||||||
for (let y = 0; y < src.height; y++) {
|
|
||||||
for (let x = 0; x < src.width; x++) {
|
|
||||||
let idx = (src.width * y + x) << 2;
|
|
||||||
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
let sample = src.data[idx + i] / 255;
|
|
||||||
sample = Math.pow(sample, 1 / 2.2 / src.gamma);
|
|
||||||
src.data[idx + i] = Math.round(sample * 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
src.gamma = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PNG.prototype.adjustGamma = function () {
|
|
||||||
PNG.adjustGamma(this);
|
|
||||||
};
|
|
||||||
168
node_modules/pngjs/lib/sync-inflate.js
generated
vendored
168
node_modules/pngjs/lib/sync-inflate.js
generated
vendored
@ -1,168 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let assert = require("assert").ok;
|
|
||||||
let zlib = require("zlib");
|
|
||||||
let util = require("util");
|
|
||||||
|
|
||||||
let kMaxLength = require("buffer").kMaxLength;
|
|
||||||
|
|
||||||
function Inflate(opts) {
|
|
||||||
if (!(this instanceof Inflate)) {
|
|
||||||
return new Inflate(opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts && opts.chunkSize < zlib.Z_MIN_CHUNK) {
|
|
||||||
opts.chunkSize = zlib.Z_MIN_CHUNK;
|
|
||||||
}
|
|
||||||
|
|
||||||
zlib.Inflate.call(this, opts);
|
|
||||||
|
|
||||||
// Node 8 --> 9 compatibility check
|
|
||||||
this._offset = this._offset === undefined ? this._outOffset : this._offset;
|
|
||||||
this._buffer = this._buffer || this._outBuffer;
|
|
||||||
|
|
||||||
if (opts && opts.maxLength != null) {
|
|
||||||
this._maxLength = opts.maxLength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createInflate(opts) {
|
|
||||||
return new Inflate(opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _close(engine, callback) {
|
|
||||||
if (callback) {
|
|
||||||
process.nextTick(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caller may invoke .close after a zlib error (which will null _handle).
|
|
||||||
if (!engine._handle) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
engine._handle.close();
|
|
||||||
engine._handle = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Inflate.prototype._processChunk = function (chunk, flushFlag, asyncCb) {
|
|
||||||
if (typeof asyncCb === "function") {
|
|
||||||
return zlib.Inflate._processChunk.call(this, chunk, flushFlag, asyncCb);
|
|
||||||
}
|
|
||||||
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
let availInBefore = chunk && chunk.length;
|
|
||||||
let availOutBefore = this._chunkSize - this._offset;
|
|
||||||
let leftToInflate = this._maxLength;
|
|
||||||
let inOff = 0;
|
|
||||||
|
|
||||||
let buffers = [];
|
|
||||||
let nread = 0;
|
|
||||||
|
|
||||||
let error;
|
|
||||||
this.on("error", function (err) {
|
|
||||||
error = err;
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleChunk(availInAfter, availOutAfter) {
|
|
||||||
if (self._hadError) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let have = availOutBefore - availOutAfter;
|
|
||||||
assert(have >= 0, "have should not go down");
|
|
||||||
|
|
||||||
if (have > 0) {
|
|
||||||
let out = self._buffer.slice(self._offset, self._offset + have);
|
|
||||||
self._offset += have;
|
|
||||||
|
|
||||||
if (out.length > leftToInflate) {
|
|
||||||
out = out.slice(0, leftToInflate);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffers.push(out);
|
|
||||||
nread += out.length;
|
|
||||||
leftToInflate -= out.length;
|
|
||||||
|
|
||||||
if (leftToInflate === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (availOutAfter === 0 || self._offset >= self._chunkSize) {
|
|
||||||
availOutBefore = self._chunkSize;
|
|
||||||
self._offset = 0;
|
|
||||||
self._buffer = Buffer.allocUnsafe(self._chunkSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (availOutAfter === 0) {
|
|
||||||
inOff += availInBefore - availInAfter;
|
|
||||||
availInBefore = availInAfter;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(this._handle, "zlib binding closed");
|
|
||||||
let res;
|
|
||||||
do {
|
|
||||||
res = this._handle.writeSync(
|
|
||||||
flushFlag,
|
|
||||||
chunk, // in
|
|
||||||
inOff, // in_off
|
|
||||||
availInBefore, // in_len
|
|
||||||
this._buffer, // out
|
|
||||||
this._offset, //out_off
|
|
||||||
availOutBefore
|
|
||||||
); // out_len
|
|
||||||
// Node 8 --> 9 compatibility check
|
|
||||||
res = res || this._writeState;
|
|
||||||
} while (!this._hadError && handleChunk(res[0], res[1]));
|
|
||||||
|
|
||||||
if (this._hadError) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nread >= kMaxLength) {
|
|
||||||
_close(this);
|
|
||||||
throw new RangeError(
|
|
||||||
"Cannot create final Buffer. It would be larger than 0x" +
|
|
||||||
kMaxLength.toString(16) +
|
|
||||||
" bytes"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let buf = Buffer.concat(buffers, nread);
|
|
||||||
_close(this);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
util.inherits(Inflate, zlib.Inflate);
|
|
||||||
|
|
||||||
function zlibBufferSync(engine, buffer) {
|
|
||||||
if (typeof buffer === "string") {
|
|
||||||
buffer = Buffer.from(buffer);
|
|
||||||
}
|
|
||||||
if (!(buffer instanceof Buffer)) {
|
|
||||||
throw new TypeError("Not a string or buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
let flushFlag = engine._finishFlushFlag;
|
|
||||||
if (flushFlag == null) {
|
|
||||||
flushFlag = zlib.Z_FINISH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return engine._processChunk(buffer, flushFlag);
|
|
||||||
}
|
|
||||||
|
|
||||||
function inflateSync(buffer, opts) {
|
|
||||||
return zlibBufferSync(new Inflate(opts), buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = exports = inflateSync;
|
|
||||||
exports.Inflate = Inflate;
|
|
||||||
exports.createInflate = createInflate;
|
|
||||||
exports.inflateSync = inflateSync;
|
|
||||||
45
node_modules/pngjs/lib/sync-reader.js
generated
vendored
45
node_modules/pngjs/lib/sync-reader.js
generated
vendored
@ -1,45 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let SyncReader = (module.exports = function (buffer) {
|
|
||||||
this._buffer = buffer;
|
|
||||||
this._reads = [];
|
|
||||||
});
|
|
||||||
|
|
||||||
SyncReader.prototype.read = function (length, callback) {
|
|
||||||
this._reads.push({
|
|
||||||
length: Math.abs(length), // if length < 0 then at most this length
|
|
||||||
allowLess: length < 0,
|
|
||||||
func: callback,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
SyncReader.prototype.process = function () {
|
|
||||||
// as long as there is any data and read requests
|
|
||||||
while (this._reads.length > 0 && this._buffer.length) {
|
|
||||||
let read = this._reads[0];
|
|
||||||
|
|
||||||
if (
|
|
||||||
this._buffer.length &&
|
|
||||||
(this._buffer.length >= read.length || read.allowLess)
|
|
||||||
) {
|
|
||||||
// ok there is any data so that we can satisfy this request
|
|
||||||
this._reads.shift(); // == read
|
|
||||||
|
|
||||||
let buf = this._buffer;
|
|
||||||
|
|
||||||
this._buffer = buf.slice(read.length);
|
|
||||||
|
|
||||||
read.func.call(this, buf.slice(0, read.length));
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._reads.length > 0) {
|
|
||||||
throw new Error("There are some read requests waitng on finished stream");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._buffer.length > 0) {
|
|
||||||
throw new Error("unrecognised content at end of stream");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
76
node_modules/pngjs/package.json
generated
vendored
76
node_modules/pngjs/package.json
generated
vendored
@ -1,76 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "pngjs",
|
|
||||||
"version": "7.0.0",
|
|
||||||
"description": "PNG encoder/decoder in pure JS, supporting any bit size & interlace, async & sync with full test suite.",
|
|
||||||
"contributors": [
|
|
||||||
"Alexandre Paré",
|
|
||||||
"Gaurav Mali",
|
|
||||||
"Gusts Kaksis",
|
|
||||||
"Kuba Niegowski",
|
|
||||||
"Luke Page",
|
|
||||||
"Pietajan De Potter",
|
|
||||||
"Steven Sojka",
|
|
||||||
"liangzeng",
|
|
||||||
"Michael Vogt",
|
|
||||||
"Xin-Xin Wang",
|
|
||||||
"toriningen",
|
|
||||||
"Eugene Kulabuhov"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/lukeapage/pngjs",
|
|
||||||
"keywords": [
|
|
||||||
"PNG",
|
|
||||||
"decoder",
|
|
||||||
"encoder",
|
|
||||||
"js-png",
|
|
||||||
"node-png",
|
|
||||||
"parser",
|
|
||||||
"png",
|
|
||||||
"png-js",
|
|
||||||
"png-parse",
|
|
||||||
"pngjs"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.19.0"
|
|
||||||
},
|
|
||||||
"main": "./lib/png.js",
|
|
||||||
"directories": {
|
|
||||||
"lib": "lib",
|
|
||||||
"example": "examples",
|
|
||||||
"test": "test"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"browser.js",
|
|
||||||
"lib/"
|
|
||||||
],
|
|
||||||
"scripts": {
|
|
||||||
"build": "yarn prepublish",
|
|
||||||
"prepublish": "yarn browserify",
|
|
||||||
"browserify": "browserify lib/png.js --standalone png > browser.js",
|
|
||||||
"coverage": "nyc --reporter=lcov --reporter=text-summary tape test/*-spec.js",
|
|
||||||
"test": "yarn lint && yarn prettier:check && tape test/*-spec.js | tap-dot && node test/run-compare",
|
|
||||||
"lint": "eslint .",
|
|
||||||
"prettier:write": "prettier --write .",
|
|
||||||
"prettier:check": "prettier --check ."
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git://github.com/pngjs/pngjs.git"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/pngjs/pngjs/issues"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"browserify": "17.0.0",
|
|
||||||
"buffer-equal": "1.0.1",
|
|
||||||
"connect": "3.7.0",
|
|
||||||
"eslint": "8.34.0",
|
|
||||||
"eslint-config-prettier": "8.6.0",
|
|
||||||
"nyc": "15.1.0",
|
|
||||||
"prettier": "2.8.4",
|
|
||||||
"puppeteer": "19.7.1",
|
|
||||||
"serve-static": "1.15.0",
|
|
||||||
"tap-dot": "2.0.0",
|
|
||||||
"tape": "5.6.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
36
package-lock.json
generated
36
package-lock.json
generated
@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "simpleshop_theme",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"devDependencies": {
|
|
||||||
"pixelmatch": "^7.1.0",
|
|
||||||
"pngjs": "^7.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pixelmatch": {
|
|
||||||
"version": "7.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-7.1.0.tgz",
|
|
||||||
"integrity": "sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"pngjs": "^7.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"pixelmatch": "bin/pixelmatch"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pngjs": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.19.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"devDependencies": {
|
|
||||||
"pixelmatch": "^7.1.0",
|
|
||||||
"pngjs": "^7.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user