@rindo/core 2.16.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +27 -0
- package/bin/rindo +57 -0
- package/cli/index.cjs +1784 -0
- package/cli/index.d.ts +15 -0
- package/cli/index.js +1758 -0
- package/cli/package.json +14 -0
- package/compiler/lib.d.ts +24 -0
- package/compiler/lib.dom.d.ts +17791 -0
- package/compiler/lib.dom.iterable.d.ts +323 -0
- package/compiler/lib.es2015.collection.d.ts +89 -0
- package/compiler/lib.es2015.core.d.ts +559 -0
- package/compiler/lib.es2015.d.ts +30 -0
- package/compiler/lib.es2015.generator.d.ts +79 -0
- package/compiler/lib.es2015.iterable.d.ts +497 -0
- package/compiler/lib.es2015.promise.d.ts +78 -0
- package/compiler/lib.es2015.proxy.d.ts +41 -0
- package/compiler/lib.es2015.reflect.d.ts +123 -0
- package/compiler/lib.es2015.symbol.d.ts +48 -0
- package/compiler/lib.es2015.symbol.wellknown.d.ts +324 -0
- package/compiler/lib.es2016.array.include.d.ts +118 -0
- package/compiler/lib.es2016.d.ts +22 -0
- package/compiler/lib.es2016.full.d.ts +25 -0
- package/compiler/lib.es2017.d.ts +26 -0
- package/compiler/lib.es2017.full.d.ts +25 -0
- package/compiler/lib.es2017.intl.d.ts +32 -0
- package/compiler/lib.es2017.object.d.ts +51 -0
- package/compiler/lib.es2017.sharedmemory.d.ts +137 -0
- package/compiler/lib.es2017.string.d.ts +47 -0
- package/compiler/lib.es2017.typedarrays.d.ts +55 -0
- package/compiler/lib.es2018.asyncgenerator.d.ts +79 -0
- package/compiler/lib.es2018.asynciterable.d.ts +45 -0
- package/compiler/lib.es2018.d.ts +26 -0
- package/compiler/lib.es2018.full.d.ts +25 -0
- package/compiler/lib.es2018.intl.d.ts +73 -0
- package/compiler/lib.es2018.promise.d.ts +32 -0
- package/compiler/lib.es2018.regexp.d.ts +39 -0
- package/compiler/lib.es2019.array.d.ts +85 -0
- package/compiler/lib.es2019.d.ts +25 -0
- package/compiler/lib.es2019.full.d.ts +25 -0
- package/compiler/lib.es2019.object.d.ts +35 -0
- package/compiler/lib.es2019.string.d.ts +39 -0
- package/compiler/lib.es2019.symbol.d.ts +26 -0
- package/compiler/lib.es2020.bigint.d.ts +728 -0
- package/compiler/lib.es2020.d.ts +27 -0
- package/compiler/lib.es2020.full.d.ts +25 -0
- package/compiler/lib.es2020.intl.d.ts +368 -0
- package/compiler/lib.es2020.promise.d.ts +49 -0
- package/compiler/lib.es2020.sharedmemory.d.ts +99 -0
- package/compiler/lib.es2020.string.d.ts +30 -0
- package/compiler/lib.es2020.symbol.wellknown.d.ts +39 -0
- package/compiler/lib.es2021.d.ts +25 -0
- package/compiler/lib.es2021.full.d.ts +25 -0
- package/compiler/lib.es2021.intl.d.ts +44 -0
- package/compiler/lib.es2021.promise.d.ts +50 -0
- package/compiler/lib.es2021.string.d.ts +35 -0
- package/compiler/lib.es2021.weakref.d.ts +75 -0
- package/compiler/lib.es5.d.ts +4495 -0
- package/compiler/lib.es6.d.ts +25 -0
- package/compiler/lib.esnext.d.ts +22 -0
- package/compiler/lib.esnext.full.d.ts +25 -0
- package/compiler/lib.esnext.intl.d.ts +23 -0
- package/compiler/lib.esnext.promise.d.ts +43 -0
- package/compiler/lib.esnext.string.d.ts +35 -0
- package/compiler/lib.esnext.weakref.d.ts +75 -0
- package/compiler/lib.scripthost.d.ts +327 -0
- package/compiler/lib.webworker.d.ts +5733 -0
- package/compiler/lib.webworker.importscripts.d.ts +26 -0
- package/compiler/lib.webworker.iterable.d.ts +160 -0
- package/compiler/package.json +8 -0
- package/compiler/rindo.d.ts +95 -0
- package/compiler/rindo.js +67222 -0
- package/compiler/rindo.min.js +4 -0
- package/dependencies.json +109 -0
- package/dev-server/client/app-error.d.ts +18 -0
- package/dev-server/client/events.d.ts +6 -0
- package/dev-server/client/hmr-components.d.ts +1 -0
- package/dev-server/client/hmr-external-styles.d.ts +1 -0
- package/dev-server/client/hmr-images.d.ts +1 -0
- package/dev-server/client/hmr-inline-styles.d.ts +1 -0
- package/dev-server/client/hmr-util.d.ts +9 -0
- package/dev-server/client/hmr-window.d.ts +10 -0
- package/dev-server/client/index.d.ts +6 -0
- package/dev-server/client/index.js +808 -0
- package/dev-server/client/logger.d.ts +5 -0
- package/dev-server/client/package.json +8 -0
- package/dev-server/client/progress.d.ts +3 -0
- package/dev-server/client/status.d.ts +4 -0
- package/dev-server/connector.html +6 -0
- package/dev-server/index.d.ts +3 -0
- package/dev-server/index.js +264 -0
- package/dev-server/open-in-editor-api.js +1 -0
- package/dev-server/package.json +8 -0
- package/dev-server/server-process.js +1763 -0
- package/dev-server/server-worker-thread.js +39 -0
- package/dev-server/static/favicon.ico +0 -0
- package/dev-server/templates/directory-index.html +132 -0
- package/dev-server/templates/initial-load.html +160 -0
- package/dev-server/visualstudio.vbs +82 -0
- package/dev-server/ws.js +1 -0
- package/dev-server/xdg-open +1066 -0
- package/internal/app-data/index.cjs +92 -0
- package/internal/app-data/index.d.ts +4 -0
- package/internal/app-data/index.js +88 -0
- package/internal/app-data/package.json +15 -0
- package/internal/client/css-shim.js +4 -0
- package/internal/client/dom.js +73 -0
- package/internal/client/index.js +3059 -0
- package/internal/client/package.json +8 -0
- package/internal/client/patch-browser.js +124 -0
- package/internal/client/patch-esm.js +23 -0
- package/internal/client/polyfills/core-js.js +11 -0
- package/internal/client/polyfills/css-shim.js +1 -0
- package/internal/client/polyfills/dom.js +79 -0
- package/internal/client/polyfills/es5-html-element.js +1 -0
- package/internal/client/polyfills/index.js +34 -0
- package/internal/client/polyfills/system.js +6 -0
- package/internal/client/shadow-css.js +387 -0
- package/internal/hydrate/index.js +1132 -0
- package/internal/hydrate/package.json +7 -0
- package/internal/hydrate/runner.d.ts +217 -0
- package/internal/hydrate/runner.js +777 -0
- package/internal/hydrate/shadow-css.js +143 -0
- package/internal/index.d.ts +4 -0
- package/internal/index.js +2 -0
- package/internal/package.json +9 -0
- package/internal/rindo-core/index.cjs +1 -0
- package/internal/rindo-core/index.d.ts +52 -0
- package/internal/rindo-core/index.js +16 -0
- package/internal/rindo-ext-modules.d.ts +41 -0
- package/internal/rindo-private.d.ts +2289 -0
- package/internal/rindo-public-compiler.d.ts +2273 -0
- package/internal/rindo-public-docs.d.ts +116 -0
- package/internal/rindo-public-runtime.d.ts +1565 -0
- package/internal/testing/index.js +1093 -0
- package/internal/testing/package.json +7 -0
- package/internal/testing/shadow-css.js +143 -0
- package/mock-doc/index.cjs +4658 -0
- package/mock-doc/index.d.ts +928 -0
- package/mock-doc/index.js +4622 -0
- package/mock-doc/package.json +15 -0
- package/package.json +151 -0
- package/readme.md +74 -0
- package/screenshot/compare/assets/favicon.ico +0 -0
- package/screenshot/compare/assets/logo.png +0 -0
- package/screenshot/compare/build/app.css +1 -0
- package/screenshot/compare/build/app.esm.js +1 -0
- package/screenshot/compare/build/app.js +33 -0
- package/screenshot/compare/build/index.esm.js +0 -0
- package/screenshot/compare/build/p-081b0641.js +1 -0
- package/screenshot/compare/build/p-227a1e18.entry.js +1 -0
- package/screenshot/compare/build/p-2c298727.entry.js +1 -0
- package/screenshot/compare/build/p-5479268c.entry.js +1 -0
- package/screenshot/compare/build/p-573ec8a4.entry.js +1 -0
- package/screenshot/compare/build/p-6ba08604.entry.js +1 -0
- package/screenshot/compare/build/p-6bc63295.entry.js +1 -0
- package/screenshot/compare/build/p-7a3759fd.entry.js +1 -0
- package/screenshot/compare/build/p-7b4e3ba7.js +1 -0
- package/screenshot/compare/build/p-988eb362.css +1 -0
- package/screenshot/compare/build/p-9b6a9315.js +1 -0
- package/screenshot/compare/build/p-b4cc611c.entry.js +1 -0
- package/screenshot/compare/build/p-d1bf53f5.entry.js +1 -0
- package/screenshot/compare/build/p-e2efe0df.js +1 -0
- package/screenshot/compare/build/p-e8ca6d97.entry.js +1 -0
- package/screenshot/compare/build/p-ec2f13e0.entry.js +1 -0
- package/screenshot/compare/build/p-f0b99977.entry.js +1 -0
- package/screenshot/compare/build/p-f4745c2f.entry.js +1 -0
- package/screenshot/compare/build/p-fbbae598.js +1 -0
- package/screenshot/compare/host.config.json +15 -0
- package/screenshot/compare/index.html +1 -0
- package/screenshot/compare/manifest.json +13 -0
- package/screenshot/connector-base.d.ts +42 -0
- package/screenshot/connector-local.d.ts +7 -0
- package/screenshot/connector.js +2 -0
- package/screenshot/index.d.ts +3 -0
- package/screenshot/index.js +659 -0
- package/screenshot/local-connector.js +2 -0
- package/screenshot/package.json +15 -0
- package/screenshot/pixel-match.d.ts +1 -0
- package/screenshot/pixel-match.js +2673 -0
- package/screenshot/screenshot-compare.d.ts +3 -0
- package/screenshot/screenshot-fs.d.ts +15 -0
- package/sys/node/autoprefixer.js +8 -0
- package/sys/node/glob.js +1 -0
- package/sys/node/graceful-fs.js +1 -0
- package/sys/node/index.d.ts +18 -0
- package/sys/node/index.js +6124 -0
- package/sys/node/node-fetch.js +1 -0
- package/sys/node/package.json +8 -0
- package/sys/node/prompts.js +1 -0
- package/sys/node/worker.js +52 -0
- package/testing/index.d.ts +12 -0
- package/testing/index.js +4232 -0
- package/testing/jest/jest-config.d.ts +16 -0
- package/testing/jest/jest-environment.d.ts +15 -0
- package/testing/jest/jest-preprocessor.d.ts +59 -0
- package/testing/jest/jest-runner.d.ts +9 -0
- package/testing/jest/jest-screenshot.d.ts +2 -0
- package/testing/jest/jest-serializer.d.ts +5 -0
- package/testing/jest/jest-setup-test-framework.d.ts +1 -0
- package/testing/jest-environment.js +3 -0
- package/testing/jest-preprocessor.js +3 -0
- package/testing/jest-preset.js +37 -0
- package/testing/jest-runner.js +3 -0
- package/testing/jest-setuptestframework.js +3 -0
- package/testing/matchers/attributes.d.ts +14 -0
- package/testing/matchers/class-list.d.ts +12 -0
- package/testing/matchers/events.d.ts +21 -0
- package/testing/matchers/html.d.ts +12 -0
- package/testing/matchers/index.d.ts +23 -0
- package/testing/matchers/screenshot.d.ts +5 -0
- package/testing/matchers/text.d.ts +4 -0
- package/testing/mock-fetch.d.ts +11 -0
- package/testing/mocks.d.ts +10 -0
- package/testing/package.json +8 -0
- package/testing/puppeteer/index.d.ts +2 -0
- package/testing/puppeteer/puppeteer-browser.d.ts +6 -0
- package/testing/puppeteer/puppeteer-declarations.d.ts +429 -0
- package/testing/puppeteer/puppeteer-element.d.ts +67 -0
- package/testing/puppeteer/puppeteer-emulate.d.ts +2 -0
- package/testing/puppeteer/puppeteer-events.d.ts +21 -0
- package/testing/puppeteer/puppeteer-page.d.ts +2 -0
- package/testing/puppeteer/puppeteer-screenshot.d.ts +4 -0
- package/testing/reset-build-conditionals.d.ts +2 -0
- package/testing/spec-page.d.ts +2 -0
- package/testing/test-transpile.d.ts +2 -0
- package/testing/testing-logger.d.ts +25 -0
- package/testing/testing-sys.d.ts +6 -0
- package/testing/testing-utils.d.ts +6 -0
- package/testing/testing.d.ts +2 -0
|
@@ -0,0 +1,2673 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var util = require('util');
|
|
5
|
+
var Stream = require('stream');
|
|
6
|
+
var zlib = require('zlib');
|
|
7
|
+
var require$$0 = require('assert');
|
|
8
|
+
var require$$1 = require('buffer');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
|
+
|
|
12
|
+
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
13
|
+
var util__default = /*#__PURE__*/_interopDefaultLegacy(util);
|
|
14
|
+
var Stream__default = /*#__PURE__*/_interopDefaultLegacy(Stream);
|
|
15
|
+
var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
|
|
16
|
+
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
|
|
17
|
+
var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
|
|
18
|
+
|
|
19
|
+
var pixelmatch_1 = pixelmatch;
|
|
20
|
+
|
|
21
|
+
function pixelmatch(img1, img2, output, width, height, options) {
|
|
22
|
+
|
|
23
|
+
if (!options) options = {};
|
|
24
|
+
|
|
25
|
+
var threshold = options.threshold === undefined ? 0.1 : options.threshold;
|
|
26
|
+
|
|
27
|
+
// maximum acceptable square distance between two colors;
|
|
28
|
+
// 35215 is the maximum possible value for the YIQ difference metric
|
|
29
|
+
var maxDelta = 35215 * threshold * threshold,
|
|
30
|
+
diff = 0;
|
|
31
|
+
|
|
32
|
+
// compare each pixel of one image against the other one
|
|
33
|
+
for (var y = 0; y < height; y++) {
|
|
34
|
+
for (var x = 0; x < width; x++) {
|
|
35
|
+
|
|
36
|
+
var pos = (y * width + x) * 4;
|
|
37
|
+
|
|
38
|
+
// squared YUV distance between colors at this pixel position
|
|
39
|
+
var delta = colorDelta(img1, img2, pos, pos);
|
|
40
|
+
|
|
41
|
+
// the color difference is above the threshold
|
|
42
|
+
if (delta > maxDelta) {
|
|
43
|
+
// check it's a real rendering difference or just anti-aliasing
|
|
44
|
+
if (!options.includeAA && (antialiased(img1, x, y, width, height, img2) ||
|
|
45
|
+
antialiased(img2, x, y, width, height, img1))) {
|
|
46
|
+
// one of the pixels is anti-aliasing; draw as yellow and do not count as difference
|
|
47
|
+
if (output) drawPixel(output, pos, 255, 255, 0);
|
|
48
|
+
|
|
49
|
+
} else {
|
|
50
|
+
// found substantial difference not caused by anti-aliasing; draw it as red
|
|
51
|
+
if (output) drawPixel(output, pos, 255, 0, 0);
|
|
52
|
+
diff++;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
} else if (output) {
|
|
56
|
+
// pixels are similar; draw background as grayscale image blended with white
|
|
57
|
+
var val = blend(grayPixel(img1, pos), 0.1);
|
|
58
|
+
drawPixel(output, pos, val, val, val);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// return the number of different pixels
|
|
64
|
+
return diff;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// check if a pixel is likely a part of anti-aliasing;
|
|
68
|
+
// based on "Anti-aliased Pixel and Intensity Slope Detector" paper by V. Vysniauskas, 2009
|
|
69
|
+
|
|
70
|
+
function antialiased(img, x1, y1, width, height, img2) {
|
|
71
|
+
var x0 = Math.max(x1 - 1, 0),
|
|
72
|
+
y0 = Math.max(y1 - 1, 0),
|
|
73
|
+
x2 = Math.min(x1 + 1, width - 1),
|
|
74
|
+
y2 = Math.min(y1 + 1, height - 1),
|
|
75
|
+
pos = (y1 * width + x1) * 4,
|
|
76
|
+
zeroes = 0,
|
|
77
|
+
positives = 0,
|
|
78
|
+
negatives = 0,
|
|
79
|
+
min = 0,
|
|
80
|
+
max = 0,
|
|
81
|
+
minX, minY, maxX, maxY;
|
|
82
|
+
|
|
83
|
+
// go through 8 adjacent pixels
|
|
84
|
+
for (var x = x0; x <= x2; x++) {
|
|
85
|
+
for (var y = y0; y <= y2; y++) {
|
|
86
|
+
if (x === x1 && y === y1) continue;
|
|
87
|
+
|
|
88
|
+
// brightness delta between the center pixel and adjacent one
|
|
89
|
+
var delta = colorDelta(img, img, pos, (y * width + x) * 4, true);
|
|
90
|
+
|
|
91
|
+
// count the number of equal, darker and brighter adjacent pixels
|
|
92
|
+
if (delta === 0) zeroes++;
|
|
93
|
+
else if (delta < 0) negatives++;
|
|
94
|
+
else if (delta > 0) positives++;
|
|
95
|
+
|
|
96
|
+
// if found more than 2 equal siblings, it's definitely not anti-aliasing
|
|
97
|
+
if (zeroes > 2) return false;
|
|
98
|
+
|
|
99
|
+
if (!img2) continue;
|
|
100
|
+
|
|
101
|
+
// remember the darkest pixel
|
|
102
|
+
if (delta < min) {
|
|
103
|
+
min = delta;
|
|
104
|
+
minX = x;
|
|
105
|
+
minY = y;
|
|
106
|
+
}
|
|
107
|
+
// remember the brightest pixel
|
|
108
|
+
if (delta > max) {
|
|
109
|
+
max = delta;
|
|
110
|
+
maxX = x;
|
|
111
|
+
maxY = y;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!img2) return true;
|
|
117
|
+
|
|
118
|
+
// if there are no both darker and brighter pixels among siblings, it's not anti-aliasing
|
|
119
|
+
if (negatives === 0 || positives === 0) return false;
|
|
120
|
+
|
|
121
|
+
// if either the darkest or the brightest pixel has more than 2 equal siblings in both images
|
|
122
|
+
// (definitely not anti-aliased), this pixel is anti-aliased
|
|
123
|
+
return (!antialiased(img, minX, minY, width, height) && !antialiased(img2, minX, minY, width, height)) ||
|
|
124
|
+
(!antialiased(img, maxX, maxY, width, height) && !antialiased(img2, maxX, maxY, width, height));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// calculate color difference according to the paper "Measuring perceived color difference
|
|
128
|
+
// using YIQ NTSC transmission color space in mobile applications" by Y. Kotsarenko and F. Ramos
|
|
129
|
+
|
|
130
|
+
function colorDelta(img1, img2, k, m, yOnly) {
|
|
131
|
+
var a1 = img1[k + 3] / 255,
|
|
132
|
+
a2 = img2[m + 3] / 255,
|
|
133
|
+
|
|
134
|
+
r1 = blend(img1[k + 0], a1),
|
|
135
|
+
g1 = blend(img1[k + 1], a1),
|
|
136
|
+
b1 = blend(img1[k + 2], a1),
|
|
137
|
+
|
|
138
|
+
r2 = blend(img2[m + 0], a2),
|
|
139
|
+
g2 = blend(img2[m + 1], a2),
|
|
140
|
+
b2 = blend(img2[m + 2], a2),
|
|
141
|
+
|
|
142
|
+
y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2);
|
|
143
|
+
|
|
144
|
+
if (yOnly) return y; // brightness difference only
|
|
145
|
+
|
|
146
|
+
var i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2),
|
|
147
|
+
q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);
|
|
148
|
+
|
|
149
|
+
return 0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function rgb2y(r, g, b) { return r * 0.29889531 + g * 0.58662247 + b * 0.11448223; }
|
|
153
|
+
function rgb2i(r, g, b) { return r * 0.59597799 - g * 0.27417610 - b * 0.32180189; }
|
|
154
|
+
function rgb2q(r, g, b) { return r * 0.21147017 - g * 0.52261711 + b * 0.31114694; }
|
|
155
|
+
|
|
156
|
+
// blend semi-transparent color with white
|
|
157
|
+
function blend(c, a) {
|
|
158
|
+
return 255 + (c - 255) * a;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function drawPixel(output, pos, r, g, b) {
|
|
162
|
+
output[pos + 0] = r;
|
|
163
|
+
output[pos + 1] = g;
|
|
164
|
+
output[pos + 2] = b;
|
|
165
|
+
output[pos + 3] = 255;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function grayPixel(img, i) {
|
|
169
|
+
var a = img[i + 3] / 255,
|
|
170
|
+
r = blend(img[i + 0], a),
|
|
171
|
+
g = blend(img[i + 1], a),
|
|
172
|
+
b = blend(img[i + 2], a);
|
|
173
|
+
return rgb2y(r, g, b);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function createCommonjsModule(fn, basedir, module) {
|
|
177
|
+
return module = {
|
|
178
|
+
path: basedir,
|
|
179
|
+
exports: {},
|
|
180
|
+
require: function (path, base) {
|
|
181
|
+
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
|
|
182
|
+
}
|
|
183
|
+
}, fn(module, module.exports), module.exports;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function commonjsRequire () {
|
|
187
|
+
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
var chunkstream = createCommonjsModule(function (module) {
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
var ChunkStream = module.exports = function() {
|
|
198
|
+
Stream__default['default'].call(this);
|
|
199
|
+
|
|
200
|
+
this._buffers = [];
|
|
201
|
+
this._buffered = 0;
|
|
202
|
+
|
|
203
|
+
this._reads = [];
|
|
204
|
+
this._paused = false;
|
|
205
|
+
|
|
206
|
+
this._encoding = 'utf8';
|
|
207
|
+
this.writable = true;
|
|
208
|
+
};
|
|
209
|
+
util__default['default'].inherits(ChunkStream, Stream__default['default']);
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
ChunkStream.prototype.read = function(length, callback) {
|
|
213
|
+
|
|
214
|
+
this._reads.push({
|
|
215
|
+
length: Math.abs(length), // if length < 0 then at most this length
|
|
216
|
+
allowLess: length < 0,
|
|
217
|
+
func: callback
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
process.nextTick(function() {
|
|
221
|
+
this._process();
|
|
222
|
+
|
|
223
|
+
// its paused and there is not enought data then ask for more
|
|
224
|
+
if (this._paused && this._reads.length > 0) {
|
|
225
|
+
this._paused = false;
|
|
226
|
+
|
|
227
|
+
this.emit('drain');
|
|
228
|
+
}
|
|
229
|
+
}.bind(this));
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
ChunkStream.prototype.write = function(data, encoding) {
|
|
233
|
+
|
|
234
|
+
if (!this.writable) {
|
|
235
|
+
this.emit('error', new Error('Stream not writable'));
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
var dataBuffer;
|
|
240
|
+
if (Buffer.isBuffer(data)) {
|
|
241
|
+
dataBuffer = data;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
dataBuffer = new Buffer(data, encoding || this._encoding);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
this._buffers.push(dataBuffer);
|
|
248
|
+
this._buffered += dataBuffer.length;
|
|
249
|
+
|
|
250
|
+
this._process();
|
|
251
|
+
|
|
252
|
+
// ok if there are no more read requests
|
|
253
|
+
if (this._reads && this._reads.length === 0) {
|
|
254
|
+
this._paused = true;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return this.writable && !this._paused;
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
ChunkStream.prototype.end = function(data, encoding) {
|
|
261
|
+
|
|
262
|
+
if (data) {
|
|
263
|
+
this.write(data, encoding);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
this.writable = false;
|
|
267
|
+
|
|
268
|
+
// already destroyed
|
|
269
|
+
if (!this._buffers) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// enqueue or handle end
|
|
274
|
+
if (this._buffers.length === 0) {
|
|
275
|
+
this._end();
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
this._buffers.push(null);
|
|
279
|
+
this._process();
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
ChunkStream.prototype.destroySoon = ChunkStream.prototype.end;
|
|
284
|
+
|
|
285
|
+
ChunkStream.prototype._end = function() {
|
|
286
|
+
|
|
287
|
+
if (this._reads.length > 0) {
|
|
288
|
+
this.emit('error',
|
|
289
|
+
new Error('Unexpected end of input')
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
this.destroy();
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
ChunkStream.prototype.destroy = function() {
|
|
297
|
+
|
|
298
|
+
if (!this._buffers) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
this.writable = false;
|
|
303
|
+
this._reads = null;
|
|
304
|
+
this._buffers = null;
|
|
305
|
+
|
|
306
|
+
this.emit('close');
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
ChunkStream.prototype._processReadAllowingLess = function(read) {
|
|
310
|
+
// ok there is any data so that we can satisfy this request
|
|
311
|
+
this._reads.shift(); // == read
|
|
312
|
+
|
|
313
|
+
// first we need to peek into first buffer
|
|
314
|
+
var smallerBuf = this._buffers[0];
|
|
315
|
+
|
|
316
|
+
// ok there is more data than we need
|
|
317
|
+
if (smallerBuf.length > read.length) {
|
|
318
|
+
|
|
319
|
+
this._buffered -= read.length;
|
|
320
|
+
this._buffers[0] = smallerBuf.slice(read.length);
|
|
321
|
+
|
|
322
|
+
read.func.call(this, smallerBuf.slice(0, read.length));
|
|
323
|
+
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
// ok this is less than maximum length so use it all
|
|
327
|
+
this._buffered -= smallerBuf.length;
|
|
328
|
+
this._buffers.shift(); // == smallerBuf
|
|
329
|
+
|
|
330
|
+
read.func.call(this, smallerBuf);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
ChunkStream.prototype._processRead = function(read) {
|
|
335
|
+
this._reads.shift(); // == read
|
|
336
|
+
|
|
337
|
+
var pos = 0;
|
|
338
|
+
var count = 0;
|
|
339
|
+
var data = new Buffer(read.length);
|
|
340
|
+
|
|
341
|
+
// create buffer for all data
|
|
342
|
+
while (pos < read.length) {
|
|
343
|
+
|
|
344
|
+
var buf = this._buffers[count++];
|
|
345
|
+
var len = Math.min(buf.length, read.length - pos);
|
|
346
|
+
|
|
347
|
+
buf.copy(data, pos, 0, len);
|
|
348
|
+
pos += len;
|
|
349
|
+
|
|
350
|
+
// last buffer wasn't used all so just slice it and leave
|
|
351
|
+
if (len !== buf.length) {
|
|
352
|
+
this._buffers[--count] = buf.slice(len);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// remove all used buffers
|
|
357
|
+
if (count > 0) {
|
|
358
|
+
this._buffers.splice(0, count);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
this._buffered -= read.length;
|
|
362
|
+
|
|
363
|
+
read.func.call(this, data);
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
ChunkStream.prototype._process = function() {
|
|
367
|
+
|
|
368
|
+
try {
|
|
369
|
+
// as long as there is any data and read requests
|
|
370
|
+
while (this._buffered > 0 && this._reads && this._reads.length > 0) {
|
|
371
|
+
|
|
372
|
+
var read = this._reads[0];
|
|
373
|
+
|
|
374
|
+
// read any data (but no more than length)
|
|
375
|
+
if (read.allowLess) {
|
|
376
|
+
this._processReadAllowingLess(read);
|
|
377
|
+
|
|
378
|
+
}
|
|
379
|
+
else if (this._buffered >= read.length) {
|
|
380
|
+
// ok we can meet some expectations
|
|
381
|
+
|
|
382
|
+
this._processRead(read);
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
// not enought data to satisfy first request in queue
|
|
386
|
+
// so we need to wait for more
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (this._buffers && !this.writable) {
|
|
392
|
+
this._end();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
catch (ex) {
|
|
396
|
+
this.emit('error', ex);
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// Adam 7
|
|
402
|
+
// 0 1 2 3 4 5 6 7
|
|
403
|
+
// 0 x 6 4 6 x 6 4 6
|
|
404
|
+
// 1 7 7 7 7 7 7 7 7
|
|
405
|
+
// 2 5 6 5 6 5 6 5 6
|
|
406
|
+
// 3 7 7 7 7 7 7 7 7
|
|
407
|
+
// 4 3 6 4 6 3 6 4 6
|
|
408
|
+
// 5 7 7 7 7 7 7 7 7
|
|
409
|
+
// 6 5 6 5 6 5 6 5 6
|
|
410
|
+
// 7 7 7 7 7 7 7 7 7
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
var imagePasses = [
|
|
414
|
+
{ // pass 1 - 1px
|
|
415
|
+
x: [0],
|
|
416
|
+
y: [0]
|
|
417
|
+
},
|
|
418
|
+
{ // pass 2 - 1px
|
|
419
|
+
x: [4],
|
|
420
|
+
y: [0]
|
|
421
|
+
},
|
|
422
|
+
{ // pass 3 - 2px
|
|
423
|
+
x: [0, 4],
|
|
424
|
+
y: [4]
|
|
425
|
+
},
|
|
426
|
+
{ // pass 4 - 4px
|
|
427
|
+
x: [2, 6],
|
|
428
|
+
y: [0, 4]
|
|
429
|
+
},
|
|
430
|
+
{ // pass 5 - 8px
|
|
431
|
+
x: [0, 2, 4, 6],
|
|
432
|
+
y: [2, 6]
|
|
433
|
+
},
|
|
434
|
+
{ // pass 6 - 16px
|
|
435
|
+
x: [1, 3, 5, 7],
|
|
436
|
+
y: [0, 2, 4, 6]
|
|
437
|
+
},
|
|
438
|
+
{ // pass 7 - 32px
|
|
439
|
+
x: [0, 1, 2, 3, 4, 5, 6, 7],
|
|
440
|
+
y: [1, 3, 5, 7]
|
|
441
|
+
}
|
|
442
|
+
];
|
|
443
|
+
|
|
444
|
+
var getImagePasses = function(width, height) {
|
|
445
|
+
var images = [];
|
|
446
|
+
var xLeftOver = width % 8;
|
|
447
|
+
var yLeftOver = height % 8;
|
|
448
|
+
var xRepeats = (width - xLeftOver) / 8;
|
|
449
|
+
var yRepeats = (height - yLeftOver) / 8;
|
|
450
|
+
for (var i = 0; i < imagePasses.length; i++) {
|
|
451
|
+
var pass = imagePasses[i];
|
|
452
|
+
var passWidth = xRepeats * pass.x.length;
|
|
453
|
+
var passHeight = yRepeats * pass.y.length;
|
|
454
|
+
for (var j = 0; j < pass.x.length; j++) {
|
|
455
|
+
if (pass.x[j] < xLeftOver) {
|
|
456
|
+
passWidth++;
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
for (j = 0; j < pass.y.length; j++) {
|
|
463
|
+
if (pass.y[j] < yLeftOver) {
|
|
464
|
+
passHeight++;
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (passWidth > 0 && passHeight > 0) {
|
|
471
|
+
images.push({ width: passWidth, height: passHeight, index: i });
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return images;
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
var getInterlaceIterator = function(width) {
|
|
478
|
+
return function(x, y, pass) {
|
|
479
|
+
var outerXLeftOver = x % imagePasses[pass].x.length;
|
|
480
|
+
var outerX = (((x - outerXLeftOver) / imagePasses[pass].x.length) * 8) + imagePasses[pass].x[outerXLeftOver];
|
|
481
|
+
var outerYLeftOver = y % imagePasses[pass].y.length;
|
|
482
|
+
var outerY = (((y - outerYLeftOver) / imagePasses[pass].y.length) * 8) + imagePasses[pass].y[outerYLeftOver];
|
|
483
|
+
return (outerX * 4) + (outerY * width * 4);
|
|
484
|
+
};
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
var interlace = {
|
|
488
|
+
getImagePasses: getImagePasses,
|
|
489
|
+
getInterlaceIterator: getInterlaceIterator
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
var paethPredictor = function paethPredictor(left, above, upLeft) {
|
|
493
|
+
|
|
494
|
+
var paeth = left + above - upLeft;
|
|
495
|
+
var pLeft = Math.abs(paeth - left);
|
|
496
|
+
var pAbove = Math.abs(paeth - above);
|
|
497
|
+
var pUpLeft = Math.abs(paeth - upLeft);
|
|
498
|
+
|
|
499
|
+
if (pLeft <= pAbove && pLeft <= pUpLeft) {
|
|
500
|
+
return left;
|
|
501
|
+
}
|
|
502
|
+
if (pAbove <= pUpLeft) {
|
|
503
|
+
return above;
|
|
504
|
+
}
|
|
505
|
+
return upLeft;
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
var filterParse = createCommonjsModule(function (module) {
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
function getByteWidth(width, bpp, depth) {
|
|
514
|
+
var byteWidth = width * bpp;
|
|
515
|
+
if (depth !== 8) {
|
|
516
|
+
byteWidth = Math.ceil(byteWidth / (8 / depth));
|
|
517
|
+
}
|
|
518
|
+
return byteWidth;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
var Filter = module.exports = function(bitmapInfo, dependencies) {
|
|
522
|
+
|
|
523
|
+
var width = bitmapInfo.width;
|
|
524
|
+
var height = bitmapInfo.height;
|
|
525
|
+
var interlace$1 = bitmapInfo.interlace;
|
|
526
|
+
var bpp = bitmapInfo.bpp;
|
|
527
|
+
var depth = bitmapInfo.depth;
|
|
528
|
+
|
|
529
|
+
this.read = dependencies.read;
|
|
530
|
+
this.write = dependencies.write;
|
|
531
|
+
this.complete = dependencies.complete;
|
|
532
|
+
|
|
533
|
+
this._imageIndex = 0;
|
|
534
|
+
this._images = [];
|
|
535
|
+
if (interlace$1) {
|
|
536
|
+
var passes = interlace.getImagePasses(width, height);
|
|
537
|
+
for (var i = 0; i < passes.length; i++) {
|
|
538
|
+
this._images.push({
|
|
539
|
+
byteWidth: getByteWidth(passes[i].width, bpp, depth),
|
|
540
|
+
height: passes[i].height,
|
|
541
|
+
lineIndex: 0
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
else {
|
|
546
|
+
this._images.push({
|
|
547
|
+
byteWidth: getByteWidth(width, bpp, depth),
|
|
548
|
+
height: height,
|
|
549
|
+
lineIndex: 0
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// when filtering the line we look at the pixel to the left
|
|
554
|
+
// the spec also says it is done on a byte level regardless of the number of pixels
|
|
555
|
+
// so if the depth is byte compatible (8 or 16) we subtract the bpp in order to compare back
|
|
556
|
+
// a pixel rather than just a different byte part. However if we are sub byte, we ignore.
|
|
557
|
+
if (depth === 8) {
|
|
558
|
+
this._xComparison = bpp;
|
|
559
|
+
}
|
|
560
|
+
else if (depth === 16) {
|
|
561
|
+
this._xComparison = bpp * 2;
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
this._xComparison = 1;
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
Filter.prototype.start = function() {
|
|
569
|
+
this.read(this._images[this._imageIndex].byteWidth + 1, this._reverseFilterLine.bind(this));
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
Filter.prototype._unFilterType1 = function(rawData, unfilteredLine, byteWidth) {
|
|
573
|
+
|
|
574
|
+
var xComparison = this._xComparison;
|
|
575
|
+
var xBiggerThan = xComparison - 1;
|
|
576
|
+
|
|
577
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
578
|
+
var rawByte = rawData[1 + x];
|
|
579
|
+
var f1Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
|
|
580
|
+
unfilteredLine[x] = rawByte + f1Left;
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
Filter.prototype._unFilterType2 = function(rawData, unfilteredLine, byteWidth) {
|
|
585
|
+
|
|
586
|
+
var lastLine = this._lastLine;
|
|
587
|
+
|
|
588
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
589
|
+
var rawByte = rawData[1 + x];
|
|
590
|
+
var f2Up = lastLine ? lastLine[x] : 0;
|
|
591
|
+
unfilteredLine[x] = rawByte + f2Up;
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
Filter.prototype._unFilterType3 = function(rawData, unfilteredLine, byteWidth) {
|
|
596
|
+
|
|
597
|
+
var xComparison = this._xComparison;
|
|
598
|
+
var xBiggerThan = xComparison - 1;
|
|
599
|
+
var lastLine = this._lastLine;
|
|
600
|
+
|
|
601
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
602
|
+
var rawByte = rawData[1 + x];
|
|
603
|
+
var f3Up = lastLine ? lastLine[x] : 0;
|
|
604
|
+
var f3Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
|
|
605
|
+
var f3Add = Math.floor((f3Left + f3Up) / 2);
|
|
606
|
+
unfilteredLine[x] = rawByte + f3Add;
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
Filter.prototype._unFilterType4 = function(rawData, unfilteredLine, byteWidth) {
|
|
611
|
+
|
|
612
|
+
var xComparison = this._xComparison;
|
|
613
|
+
var xBiggerThan = xComparison - 1;
|
|
614
|
+
var lastLine = this._lastLine;
|
|
615
|
+
|
|
616
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
617
|
+
var rawByte = rawData[1 + x];
|
|
618
|
+
var f4Up = lastLine ? lastLine[x] : 0;
|
|
619
|
+
var f4Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
|
|
620
|
+
var f4UpLeft = x > xBiggerThan && lastLine ? lastLine[x - xComparison] : 0;
|
|
621
|
+
var f4Add = paethPredictor(f4Left, f4Up, f4UpLeft);
|
|
622
|
+
unfilteredLine[x] = rawByte + f4Add;
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
Filter.prototype._reverseFilterLine = function(rawData) {
|
|
627
|
+
|
|
628
|
+
var filter = rawData[0];
|
|
629
|
+
var unfilteredLine;
|
|
630
|
+
var currentImage = this._images[this._imageIndex];
|
|
631
|
+
var byteWidth = currentImage.byteWidth;
|
|
632
|
+
|
|
633
|
+
if (filter === 0) {
|
|
634
|
+
unfilteredLine = rawData.slice(1, byteWidth + 1);
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
|
|
638
|
+
unfilteredLine = new Buffer(byteWidth);
|
|
639
|
+
|
|
640
|
+
switch (filter) {
|
|
641
|
+
case 1:
|
|
642
|
+
this._unFilterType1(rawData, unfilteredLine, byteWidth);
|
|
643
|
+
break;
|
|
644
|
+
case 2:
|
|
645
|
+
this._unFilterType2(rawData, unfilteredLine, byteWidth);
|
|
646
|
+
break;
|
|
647
|
+
case 3:
|
|
648
|
+
this._unFilterType3(rawData, unfilteredLine, byteWidth);
|
|
649
|
+
break;
|
|
650
|
+
case 4:
|
|
651
|
+
this._unFilterType4(rawData, unfilteredLine, byteWidth);
|
|
652
|
+
break;
|
|
653
|
+
default:
|
|
654
|
+
throw new Error('Unrecognised filter type - ' + filter);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
this.write(unfilteredLine);
|
|
659
|
+
|
|
660
|
+
currentImage.lineIndex++;
|
|
661
|
+
if (currentImage.lineIndex >= currentImage.height) {
|
|
662
|
+
this._lastLine = null;
|
|
663
|
+
this._imageIndex++;
|
|
664
|
+
currentImage = this._images[this._imageIndex];
|
|
665
|
+
}
|
|
666
|
+
else {
|
|
667
|
+
this._lastLine = unfilteredLine;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (currentImage) {
|
|
671
|
+
// read, using the byte width that may be from the new current image
|
|
672
|
+
this.read(currentImage.byteWidth + 1, this._reverseFilterLine.bind(this));
|
|
673
|
+
}
|
|
674
|
+
else {
|
|
675
|
+
this._lastLine = null;
|
|
676
|
+
this.complete();
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
var filterParseAsync = createCommonjsModule(function (module) {
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
var FilterAsync = module.exports = function(bitmapInfo) {
|
|
689
|
+
chunkstream.call(this);
|
|
690
|
+
|
|
691
|
+
var buffers = [];
|
|
692
|
+
var that = this;
|
|
693
|
+
this._filter = new filterParse(bitmapInfo, {
|
|
694
|
+
read: this.read.bind(this),
|
|
695
|
+
write: function(buffer) {
|
|
696
|
+
buffers.push(buffer);
|
|
697
|
+
},
|
|
698
|
+
complete: function() {
|
|
699
|
+
that.emit('complete', Buffer.concat(buffers));
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
this._filter.start();
|
|
704
|
+
};
|
|
705
|
+
util__default['default'].inherits(FilterAsync, chunkstream);
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
var constants = {
|
|
709
|
+
|
|
710
|
+
PNG_SIGNATURE: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a],
|
|
711
|
+
|
|
712
|
+
TYPE_IHDR: 0x49484452,
|
|
713
|
+
TYPE_IEND: 0x49454e44,
|
|
714
|
+
TYPE_IDAT: 0x49444154,
|
|
715
|
+
TYPE_PLTE: 0x504c5445,
|
|
716
|
+
TYPE_tRNS: 0x74524e53, // eslint-disable-line camelcase
|
|
717
|
+
TYPE_gAMA: 0x67414d41, // eslint-disable-line camelcase
|
|
718
|
+
|
|
719
|
+
// color-type bits
|
|
720
|
+
COLORTYPE_GRAYSCALE: 0,
|
|
721
|
+
COLORTYPE_PALETTE: 1,
|
|
722
|
+
COLORTYPE_COLOR: 2,
|
|
723
|
+
COLORTYPE_ALPHA: 4, // e.g. grayscale and alpha
|
|
724
|
+
|
|
725
|
+
// color-type combinations
|
|
726
|
+
COLORTYPE_PALETTE_COLOR: 3,
|
|
727
|
+
COLORTYPE_COLOR_ALPHA: 6,
|
|
728
|
+
|
|
729
|
+
COLORTYPE_TO_BPP_MAP: {
|
|
730
|
+
0: 1,
|
|
731
|
+
2: 3,
|
|
732
|
+
3: 1,
|
|
733
|
+
4: 2,
|
|
734
|
+
6: 4
|
|
735
|
+
},
|
|
736
|
+
|
|
737
|
+
GAMMA_DIVISION: 100000
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
var crc = createCommonjsModule(function (module) {
|
|
741
|
+
|
|
742
|
+
var crcTable = [];
|
|
743
|
+
|
|
744
|
+
(function() {
|
|
745
|
+
for (var i = 0; i < 256; i++) {
|
|
746
|
+
var currentCrc = i;
|
|
747
|
+
for (var j = 0; j < 8; j++) {
|
|
748
|
+
if (currentCrc & 1) {
|
|
749
|
+
currentCrc = 0xedb88320 ^ (currentCrc >>> 1);
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
currentCrc = currentCrc >>> 1;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
crcTable[i] = currentCrc;
|
|
756
|
+
}
|
|
757
|
+
}());
|
|
758
|
+
|
|
759
|
+
var CrcCalculator = module.exports = function() {
|
|
760
|
+
this._crc = -1;
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
CrcCalculator.prototype.write = function(data) {
|
|
764
|
+
|
|
765
|
+
for (var i = 0; i < data.length; i++) {
|
|
766
|
+
this._crc = crcTable[(this._crc ^ data[i]) & 0xff] ^ (this._crc >>> 8);
|
|
767
|
+
}
|
|
768
|
+
return true;
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
CrcCalculator.prototype.crc32 = function() {
|
|
772
|
+
return this._crc ^ -1;
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
CrcCalculator.crc32 = function(buf) {
|
|
777
|
+
|
|
778
|
+
var crc = -1;
|
|
779
|
+
for (var i = 0; i < buf.length; i++) {
|
|
780
|
+
crc = crcTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
|
|
781
|
+
}
|
|
782
|
+
return crc ^ -1;
|
|
783
|
+
};
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
var parser = createCommonjsModule(function (module) {
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
var Parser = module.exports = function(options, dependencies) {
|
|
793
|
+
|
|
794
|
+
this._options = options;
|
|
795
|
+
options.checkCRC = options.checkCRC !== false;
|
|
796
|
+
|
|
797
|
+
this._hasIHDR = false;
|
|
798
|
+
this._hasIEND = false;
|
|
799
|
+
this._emittedHeadersFinished = false;
|
|
800
|
+
|
|
801
|
+
// input flags/metadata
|
|
802
|
+
this._palette = [];
|
|
803
|
+
this._colorType = 0;
|
|
804
|
+
|
|
805
|
+
this._chunks = {};
|
|
806
|
+
this._chunks[constants.TYPE_IHDR] = this._handleIHDR.bind(this);
|
|
807
|
+
this._chunks[constants.TYPE_IEND] = this._handleIEND.bind(this);
|
|
808
|
+
this._chunks[constants.TYPE_IDAT] = this._handleIDAT.bind(this);
|
|
809
|
+
this._chunks[constants.TYPE_PLTE] = this._handlePLTE.bind(this);
|
|
810
|
+
this._chunks[constants.TYPE_tRNS] = this._handleTRNS.bind(this);
|
|
811
|
+
this._chunks[constants.TYPE_gAMA] = this._handleGAMA.bind(this);
|
|
812
|
+
|
|
813
|
+
this.read = dependencies.read;
|
|
814
|
+
this.error = dependencies.error;
|
|
815
|
+
this.metadata = dependencies.metadata;
|
|
816
|
+
this.gamma = dependencies.gamma;
|
|
817
|
+
this.transColor = dependencies.transColor;
|
|
818
|
+
this.palette = dependencies.palette;
|
|
819
|
+
this.parsed = dependencies.parsed;
|
|
820
|
+
this.inflateData = dependencies.inflateData;
|
|
821
|
+
this.finished = dependencies.finished;
|
|
822
|
+
this.simpleTransparency = dependencies.simpleTransparency;
|
|
823
|
+
this.headersFinished = dependencies.headersFinished || function() {};
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
Parser.prototype.start = function() {
|
|
827
|
+
this.read(constants.PNG_SIGNATURE.length,
|
|
828
|
+
this._parseSignature.bind(this)
|
|
829
|
+
);
|
|
830
|
+
};
|
|
831
|
+
|
|
832
|
+
Parser.prototype._parseSignature = function(data) {
|
|
833
|
+
|
|
834
|
+
var signature = constants.PNG_SIGNATURE;
|
|
835
|
+
|
|
836
|
+
for (var i = 0; i < signature.length; i++) {
|
|
837
|
+
if (data[i] !== signature[i]) {
|
|
838
|
+
this.error(new Error('Invalid file signature'));
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
this.read(8, this._parseChunkBegin.bind(this));
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
Parser.prototype._parseChunkBegin = function(data) {
|
|
846
|
+
|
|
847
|
+
// chunk content length
|
|
848
|
+
var length = data.readUInt32BE(0);
|
|
849
|
+
|
|
850
|
+
// chunk type
|
|
851
|
+
var type = data.readUInt32BE(4);
|
|
852
|
+
var name = '';
|
|
853
|
+
for (var i = 4; i < 8; i++) {
|
|
854
|
+
name += String.fromCharCode(data[i]);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
//console.log('chunk ', name, length);
|
|
858
|
+
|
|
859
|
+
// chunk flags
|
|
860
|
+
var ancillary = Boolean(data[4] & 0x20); // or critical
|
|
861
|
+
// priv = Boolean(data[5] & 0x20), // or public
|
|
862
|
+
// safeToCopy = Boolean(data[7] & 0x20); // or unsafe
|
|
863
|
+
|
|
864
|
+
if (!this._hasIHDR && type !== constants.TYPE_IHDR) {
|
|
865
|
+
this.error(new Error('Expected IHDR on beggining'));
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
this._crc = new crc();
|
|
870
|
+
this._crc.write(new Buffer(name));
|
|
871
|
+
|
|
872
|
+
if (this._chunks[type]) {
|
|
873
|
+
return this._chunks[type](length);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
if (!ancillary) {
|
|
877
|
+
this.error(new Error('Unsupported critical chunk type ' + name));
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
this.read(length + 4, this._skipChunk.bind(this));
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
Parser.prototype._skipChunk = function(/*data*/) {
|
|
885
|
+
this.read(8, this._parseChunkBegin.bind(this));
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
Parser.prototype._handleChunkEnd = function() {
|
|
889
|
+
this.read(4, this._parseChunkEnd.bind(this));
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
Parser.prototype._parseChunkEnd = function(data) {
|
|
893
|
+
|
|
894
|
+
var fileCrc = data.readInt32BE(0);
|
|
895
|
+
var calcCrc = this._crc.crc32();
|
|
896
|
+
|
|
897
|
+
// check CRC
|
|
898
|
+
if (this._options.checkCRC && calcCrc !== fileCrc) {
|
|
899
|
+
this.error(new Error('Crc error - ' + fileCrc + ' - ' + calcCrc));
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
if (!this._hasIEND) {
|
|
904
|
+
this.read(8, this._parseChunkBegin.bind(this));
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
Parser.prototype._handleIHDR = function(length) {
|
|
909
|
+
this.read(length, this._parseIHDR.bind(this));
|
|
910
|
+
};
|
|
911
|
+
Parser.prototype._parseIHDR = function(data) {
|
|
912
|
+
|
|
913
|
+
this._crc.write(data);
|
|
914
|
+
|
|
915
|
+
var width = data.readUInt32BE(0);
|
|
916
|
+
var height = data.readUInt32BE(4);
|
|
917
|
+
var depth = data[8];
|
|
918
|
+
var colorType = data[9]; // bits: 1 palette, 2 color, 4 alpha
|
|
919
|
+
var compr = data[10];
|
|
920
|
+
var filter = data[11];
|
|
921
|
+
var interlace = data[12];
|
|
922
|
+
|
|
923
|
+
// console.log(' width', width, 'height', height,
|
|
924
|
+
// 'depth', depth, 'colorType', colorType,
|
|
925
|
+
// 'compr', compr, 'filter', filter, 'interlace', interlace
|
|
926
|
+
// );
|
|
927
|
+
|
|
928
|
+
if (depth !== 8 && depth !== 4 && depth !== 2 && depth !== 1 && depth !== 16) {
|
|
929
|
+
this.error(new Error('Unsupported bit depth ' + depth));
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
if (!(colorType in constants.COLORTYPE_TO_BPP_MAP)) {
|
|
933
|
+
this.error(new Error('Unsupported color type'));
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
if (compr !== 0) {
|
|
937
|
+
this.error(new Error('Unsupported compression method'));
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
if (filter !== 0) {
|
|
941
|
+
this.error(new Error('Unsupported filter method'));
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (interlace !== 0 && interlace !== 1) {
|
|
945
|
+
this.error(new Error('Unsupported interlace method'));
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
this._colorType = colorType;
|
|
950
|
+
|
|
951
|
+
var bpp = constants.COLORTYPE_TO_BPP_MAP[this._colorType];
|
|
952
|
+
|
|
953
|
+
this._hasIHDR = true;
|
|
954
|
+
|
|
955
|
+
this.metadata({
|
|
956
|
+
width: width,
|
|
957
|
+
height: height,
|
|
958
|
+
depth: depth,
|
|
959
|
+
interlace: Boolean(interlace),
|
|
960
|
+
palette: Boolean(colorType & constants.COLORTYPE_PALETTE),
|
|
961
|
+
color: Boolean(colorType & constants.COLORTYPE_COLOR),
|
|
962
|
+
alpha: Boolean(colorType & constants.COLORTYPE_ALPHA),
|
|
963
|
+
bpp: bpp,
|
|
964
|
+
colorType: colorType
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
this._handleChunkEnd();
|
|
968
|
+
};
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
Parser.prototype._handlePLTE = function(length) {
|
|
972
|
+
this.read(length, this._parsePLTE.bind(this));
|
|
973
|
+
};
|
|
974
|
+
Parser.prototype._parsePLTE = function(data) {
|
|
975
|
+
|
|
976
|
+
this._crc.write(data);
|
|
977
|
+
|
|
978
|
+
var entries = Math.floor(data.length / 3);
|
|
979
|
+
// console.log('Palette:', entries);
|
|
980
|
+
|
|
981
|
+
for (var i = 0; i < entries; i++) {
|
|
982
|
+
this._palette.push([
|
|
983
|
+
data[i * 3],
|
|
984
|
+
data[i * 3 + 1],
|
|
985
|
+
data[i * 3 + 2],
|
|
986
|
+
0xff
|
|
987
|
+
]);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
this.palette(this._palette);
|
|
991
|
+
|
|
992
|
+
this._handleChunkEnd();
|
|
993
|
+
};
|
|
994
|
+
|
|
995
|
+
Parser.prototype._handleTRNS = function(length) {
|
|
996
|
+
this.simpleTransparency();
|
|
997
|
+
this.read(length, this._parseTRNS.bind(this));
|
|
998
|
+
};
|
|
999
|
+
Parser.prototype._parseTRNS = function(data) {
|
|
1000
|
+
|
|
1001
|
+
this._crc.write(data);
|
|
1002
|
+
|
|
1003
|
+
// palette
|
|
1004
|
+
if (this._colorType === constants.COLORTYPE_PALETTE_COLOR) {
|
|
1005
|
+
if (this._palette.length === 0) {
|
|
1006
|
+
this.error(new Error('Transparency chunk must be after palette'));
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
if (data.length > this._palette.length) {
|
|
1010
|
+
this.error(new Error('More transparent colors than palette size'));
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
for (var i = 0; i < data.length; i++) {
|
|
1014
|
+
this._palette[i][3] = data[i];
|
|
1015
|
+
}
|
|
1016
|
+
this.palette(this._palette);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// for colorType 0 (grayscale) and 2 (rgb)
|
|
1020
|
+
// there might be one gray/color defined as transparent
|
|
1021
|
+
if (this._colorType === constants.COLORTYPE_GRAYSCALE) {
|
|
1022
|
+
// grey, 2 bytes
|
|
1023
|
+
this.transColor([data.readUInt16BE(0)]);
|
|
1024
|
+
}
|
|
1025
|
+
if (this._colorType === constants.COLORTYPE_COLOR) {
|
|
1026
|
+
this.transColor([data.readUInt16BE(0), data.readUInt16BE(2), data.readUInt16BE(4)]);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
this._handleChunkEnd();
|
|
1030
|
+
};
|
|
1031
|
+
|
|
1032
|
+
Parser.prototype._handleGAMA = function(length) {
|
|
1033
|
+
this.read(length, this._parseGAMA.bind(this));
|
|
1034
|
+
};
|
|
1035
|
+
Parser.prototype._parseGAMA = function(data) {
|
|
1036
|
+
|
|
1037
|
+
this._crc.write(data);
|
|
1038
|
+
this.gamma(data.readUInt32BE(0) / constants.GAMMA_DIVISION);
|
|
1039
|
+
|
|
1040
|
+
this._handleChunkEnd();
|
|
1041
|
+
};
|
|
1042
|
+
|
|
1043
|
+
Parser.prototype._handleIDAT = function(length) {
|
|
1044
|
+
if (!this._emittedHeadersFinished) {
|
|
1045
|
+
this._emittedHeadersFinished = true;
|
|
1046
|
+
this.headersFinished();
|
|
1047
|
+
}
|
|
1048
|
+
this.read(-length, this._parseIDAT.bind(this, length));
|
|
1049
|
+
};
|
|
1050
|
+
Parser.prototype._parseIDAT = function(length, data) {
|
|
1051
|
+
|
|
1052
|
+
this._crc.write(data);
|
|
1053
|
+
|
|
1054
|
+
if (this._colorType === constants.COLORTYPE_PALETTE_COLOR && this._palette.length === 0) {
|
|
1055
|
+
throw new Error('Expected palette not found');
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
this.inflateData(data);
|
|
1059
|
+
var leftOverLength = length - data.length;
|
|
1060
|
+
|
|
1061
|
+
if (leftOverLength > 0) {
|
|
1062
|
+
this._handleIDAT(leftOverLength);
|
|
1063
|
+
}
|
|
1064
|
+
else {
|
|
1065
|
+
this._handleChunkEnd();
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
|
|
1069
|
+
Parser.prototype._handleIEND = function(length) {
|
|
1070
|
+
this.read(length, this._parseIEND.bind(this));
|
|
1071
|
+
};
|
|
1072
|
+
Parser.prototype._parseIEND = function(data) {
|
|
1073
|
+
|
|
1074
|
+
this._crc.write(data);
|
|
1075
|
+
|
|
1076
|
+
this._hasIEND = true;
|
|
1077
|
+
this._handleChunkEnd();
|
|
1078
|
+
|
|
1079
|
+
if (this.finished) {
|
|
1080
|
+
this.finished();
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
var pixelBppMapper = [
|
|
1086
|
+
// 0 - dummy entry
|
|
1087
|
+
function() {},
|
|
1088
|
+
|
|
1089
|
+
// 1 - L
|
|
1090
|
+
// 0: 0, 1: 0, 2: 0, 3: 0xff
|
|
1091
|
+
function(pxData, data, pxPos, rawPos) {
|
|
1092
|
+
if (rawPos === data.length) {
|
|
1093
|
+
throw new Error('Ran out of data');
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
var pixel = data[rawPos];
|
|
1097
|
+
pxData[pxPos] = pixel;
|
|
1098
|
+
pxData[pxPos + 1] = pixel;
|
|
1099
|
+
pxData[pxPos + 2] = pixel;
|
|
1100
|
+
pxData[pxPos + 3] = 0xff;
|
|
1101
|
+
},
|
|
1102
|
+
|
|
1103
|
+
// 2 - LA
|
|
1104
|
+
// 0: 0, 1: 0, 2: 0, 3: 1
|
|
1105
|
+
function(pxData, data, pxPos, rawPos) {
|
|
1106
|
+
if (rawPos + 1 >= data.length) {
|
|
1107
|
+
throw new Error('Ran out of data');
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
var pixel = data[rawPos];
|
|
1111
|
+
pxData[pxPos] = pixel;
|
|
1112
|
+
pxData[pxPos + 1] = pixel;
|
|
1113
|
+
pxData[pxPos + 2] = pixel;
|
|
1114
|
+
pxData[pxPos + 3] = data[rawPos + 1];
|
|
1115
|
+
},
|
|
1116
|
+
|
|
1117
|
+
// 3 - RGB
|
|
1118
|
+
// 0: 0, 1: 1, 2: 2, 3: 0xff
|
|
1119
|
+
function(pxData, data, pxPos, rawPos) {
|
|
1120
|
+
if (rawPos + 2 >= data.length) {
|
|
1121
|
+
throw new Error('Ran out of data');
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
pxData[pxPos] = data[rawPos];
|
|
1125
|
+
pxData[pxPos + 1] = data[rawPos + 1];
|
|
1126
|
+
pxData[pxPos + 2] = data[rawPos + 2];
|
|
1127
|
+
pxData[pxPos + 3] = 0xff;
|
|
1128
|
+
},
|
|
1129
|
+
|
|
1130
|
+
// 4 - RGBA
|
|
1131
|
+
// 0: 0, 1: 1, 2: 2, 3: 3
|
|
1132
|
+
function(pxData, data, pxPos, rawPos) {
|
|
1133
|
+
if (rawPos + 3 >= data.length) {
|
|
1134
|
+
throw new Error('Ran out of data');
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
pxData[pxPos] = data[rawPos];
|
|
1138
|
+
pxData[pxPos + 1] = data[rawPos + 1];
|
|
1139
|
+
pxData[pxPos + 2] = data[rawPos + 2];
|
|
1140
|
+
pxData[pxPos + 3] = data[rawPos + 3];
|
|
1141
|
+
}
|
|
1142
|
+
];
|
|
1143
|
+
|
|
1144
|
+
var pixelBppCustomMapper = [
|
|
1145
|
+
// 0 - dummy entry
|
|
1146
|
+
function() {},
|
|
1147
|
+
|
|
1148
|
+
// 1 - L
|
|
1149
|
+
// 0: 0, 1: 0, 2: 0, 3: 0xff
|
|
1150
|
+
function(pxData, pixelData, pxPos, maxBit) {
|
|
1151
|
+
var pixel = pixelData[0];
|
|
1152
|
+
pxData[pxPos] = pixel;
|
|
1153
|
+
pxData[pxPos + 1] = pixel;
|
|
1154
|
+
pxData[pxPos + 2] = pixel;
|
|
1155
|
+
pxData[pxPos + 3] = maxBit;
|
|
1156
|
+
},
|
|
1157
|
+
|
|
1158
|
+
// 2 - LA
|
|
1159
|
+
// 0: 0, 1: 0, 2: 0, 3: 1
|
|
1160
|
+
function(pxData, pixelData, pxPos) {
|
|
1161
|
+
var pixel = pixelData[0];
|
|
1162
|
+
pxData[pxPos] = pixel;
|
|
1163
|
+
pxData[pxPos + 1] = pixel;
|
|
1164
|
+
pxData[pxPos + 2] = pixel;
|
|
1165
|
+
pxData[pxPos + 3] = pixelData[1];
|
|
1166
|
+
},
|
|
1167
|
+
|
|
1168
|
+
// 3 - RGB
|
|
1169
|
+
// 0: 0, 1: 1, 2: 2, 3: 0xff
|
|
1170
|
+
function(pxData, pixelData, pxPos, maxBit) {
|
|
1171
|
+
pxData[pxPos] = pixelData[0];
|
|
1172
|
+
pxData[pxPos + 1] = pixelData[1];
|
|
1173
|
+
pxData[pxPos + 2] = pixelData[2];
|
|
1174
|
+
pxData[pxPos + 3] = maxBit;
|
|
1175
|
+
},
|
|
1176
|
+
|
|
1177
|
+
// 4 - RGBA
|
|
1178
|
+
// 0: 0, 1: 1, 2: 2, 3: 3
|
|
1179
|
+
function(pxData, pixelData, pxPos) {
|
|
1180
|
+
pxData[pxPos] = pixelData[0];
|
|
1181
|
+
pxData[pxPos + 1] = pixelData[1];
|
|
1182
|
+
pxData[pxPos + 2] = pixelData[2];
|
|
1183
|
+
pxData[pxPos + 3] = pixelData[3];
|
|
1184
|
+
}
|
|
1185
|
+
];
|
|
1186
|
+
|
|
1187
|
+
function bitRetriever(data, depth) {
|
|
1188
|
+
|
|
1189
|
+
var leftOver = [];
|
|
1190
|
+
var i = 0;
|
|
1191
|
+
|
|
1192
|
+
function split() {
|
|
1193
|
+
if (i === data.length) {
|
|
1194
|
+
throw new Error('Ran out of data');
|
|
1195
|
+
}
|
|
1196
|
+
var byte = data[i];
|
|
1197
|
+
i++;
|
|
1198
|
+
var byte8, byte7, byte6, byte5, byte4, byte3, byte2, byte1;
|
|
1199
|
+
switch (depth) {
|
|
1200
|
+
default:
|
|
1201
|
+
throw new Error('unrecognised depth');
|
|
1202
|
+
case 16:
|
|
1203
|
+
byte2 = data[i];
|
|
1204
|
+
i++;
|
|
1205
|
+
leftOver.push(((byte << 8) + byte2));
|
|
1206
|
+
break;
|
|
1207
|
+
case 4:
|
|
1208
|
+
byte2 = byte & 0x0f;
|
|
1209
|
+
byte1 = byte >> 4;
|
|
1210
|
+
leftOver.push(byte1, byte2);
|
|
1211
|
+
break;
|
|
1212
|
+
case 2:
|
|
1213
|
+
byte4 = byte & 3;
|
|
1214
|
+
byte3 = byte >> 2 & 3;
|
|
1215
|
+
byte2 = byte >> 4 & 3;
|
|
1216
|
+
byte1 = byte >> 6 & 3;
|
|
1217
|
+
leftOver.push(byte1, byte2, byte3, byte4);
|
|
1218
|
+
break;
|
|
1219
|
+
case 1:
|
|
1220
|
+
byte8 = byte & 1;
|
|
1221
|
+
byte7 = byte >> 1 & 1;
|
|
1222
|
+
byte6 = byte >> 2 & 1;
|
|
1223
|
+
byte5 = byte >> 3 & 1;
|
|
1224
|
+
byte4 = byte >> 4 & 1;
|
|
1225
|
+
byte3 = byte >> 5 & 1;
|
|
1226
|
+
byte2 = byte >> 6 & 1;
|
|
1227
|
+
byte1 = byte >> 7 & 1;
|
|
1228
|
+
leftOver.push(byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8);
|
|
1229
|
+
break;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
return {
|
|
1234
|
+
get: function(count) {
|
|
1235
|
+
while (leftOver.length < count) {
|
|
1236
|
+
split();
|
|
1237
|
+
}
|
|
1238
|
+
var returner = leftOver.slice(0, count);
|
|
1239
|
+
leftOver = leftOver.slice(count);
|
|
1240
|
+
return returner;
|
|
1241
|
+
},
|
|
1242
|
+
resetAfterLine: function() {
|
|
1243
|
+
leftOver.length = 0;
|
|
1244
|
+
},
|
|
1245
|
+
end: function() {
|
|
1246
|
+
if (i !== data.length) {
|
|
1247
|
+
throw new Error('extra data found');
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
function mapImage8Bit(image, pxData, getPxPos, bpp, data, rawPos) { // eslint-disable-line max-params
|
|
1254
|
+
var imageWidth = image.width;
|
|
1255
|
+
var imageHeight = image.height;
|
|
1256
|
+
var imagePass = image.index;
|
|
1257
|
+
for (var y = 0; y < imageHeight; y++) {
|
|
1258
|
+
for (var x = 0; x < imageWidth; x++) {
|
|
1259
|
+
var pxPos = getPxPos(x, y, imagePass);
|
|
1260
|
+
pixelBppMapper[bpp](pxData, data, pxPos, rawPos);
|
|
1261
|
+
rawPos += bpp; //eslint-disable-line no-param-reassign
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
return rawPos;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
function mapImageCustomBit(image, pxData, getPxPos, bpp, bits, maxBit) { // eslint-disable-line max-params
|
|
1268
|
+
var imageWidth = image.width;
|
|
1269
|
+
var imageHeight = image.height;
|
|
1270
|
+
var imagePass = image.index;
|
|
1271
|
+
for (var y = 0; y < imageHeight; y++) {
|
|
1272
|
+
for (var x = 0; x < imageWidth; x++) {
|
|
1273
|
+
var pixelData = bits.get(bpp);
|
|
1274
|
+
var pxPos = getPxPos(x, y, imagePass);
|
|
1275
|
+
pixelBppCustomMapper[bpp](pxData, pixelData, pxPos, maxBit);
|
|
1276
|
+
}
|
|
1277
|
+
bits.resetAfterLine();
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
var dataToBitMap = function(data, bitmapInfo) {
|
|
1282
|
+
|
|
1283
|
+
var width = bitmapInfo.width;
|
|
1284
|
+
var height = bitmapInfo.height;
|
|
1285
|
+
var depth = bitmapInfo.depth;
|
|
1286
|
+
var bpp = bitmapInfo.bpp;
|
|
1287
|
+
var interlace$1 = bitmapInfo.interlace;
|
|
1288
|
+
|
|
1289
|
+
if (depth !== 8) {
|
|
1290
|
+
var bits = bitRetriever(data, depth);
|
|
1291
|
+
}
|
|
1292
|
+
var pxData;
|
|
1293
|
+
if (depth <= 8) {
|
|
1294
|
+
pxData = new Buffer(width * height * 4);
|
|
1295
|
+
}
|
|
1296
|
+
else {
|
|
1297
|
+
pxData = new Uint16Array(width * height * 4);
|
|
1298
|
+
}
|
|
1299
|
+
var maxBit = Math.pow(2, depth) - 1;
|
|
1300
|
+
var rawPos = 0;
|
|
1301
|
+
var images;
|
|
1302
|
+
var getPxPos;
|
|
1303
|
+
|
|
1304
|
+
if (interlace$1) {
|
|
1305
|
+
images = interlace.getImagePasses(width, height);
|
|
1306
|
+
getPxPos = interlace.getInterlaceIterator(width, height);
|
|
1307
|
+
}
|
|
1308
|
+
else {
|
|
1309
|
+
var nonInterlacedPxPos = 0;
|
|
1310
|
+
getPxPos = function() {
|
|
1311
|
+
var returner = nonInterlacedPxPos;
|
|
1312
|
+
nonInterlacedPxPos += 4;
|
|
1313
|
+
return returner;
|
|
1314
|
+
};
|
|
1315
|
+
images = [{ width: width, height: height }];
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
for (var imageIndex = 0; imageIndex < images.length; imageIndex++) {
|
|
1319
|
+
if (depth === 8) {
|
|
1320
|
+
rawPos = mapImage8Bit(images[imageIndex], pxData, getPxPos, bpp, data, rawPos);
|
|
1321
|
+
}
|
|
1322
|
+
else {
|
|
1323
|
+
mapImageCustomBit(images[imageIndex], pxData, getPxPos, bpp, bits, maxBit);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
if (depth === 8) {
|
|
1327
|
+
if (rawPos !== data.length) {
|
|
1328
|
+
throw new Error('extra data found');
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
else {
|
|
1332
|
+
bits.end();
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
return pxData;
|
|
1336
|
+
};
|
|
1337
|
+
|
|
1338
|
+
var bitmapper = {
|
|
1339
|
+
dataToBitMap: dataToBitMap
|
|
1340
|
+
};
|
|
1341
|
+
|
|
1342
|
+
function dePalette(indata, outdata, width, height, palette) {
|
|
1343
|
+
var pxPos = 0;
|
|
1344
|
+
// use values from palette
|
|
1345
|
+
for (var y = 0; y < height; y++) {
|
|
1346
|
+
for (var x = 0; x < width; x++) {
|
|
1347
|
+
var color = palette[indata[pxPos]];
|
|
1348
|
+
|
|
1349
|
+
if (!color) {
|
|
1350
|
+
throw new Error('index ' + indata[pxPos] + ' not in palette');
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
for (var i = 0; i < 4; i++) {
|
|
1354
|
+
outdata[pxPos + i] = color[i];
|
|
1355
|
+
}
|
|
1356
|
+
pxPos += 4;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
function replaceTransparentColor(indata, outdata, width, height, transColor) {
|
|
1362
|
+
var pxPos = 0;
|
|
1363
|
+
for (var y = 0; y < height; y++) {
|
|
1364
|
+
for (var x = 0; x < width; x++) {
|
|
1365
|
+
var makeTrans = false;
|
|
1366
|
+
|
|
1367
|
+
if (transColor.length === 1) {
|
|
1368
|
+
if (transColor[0] === indata[pxPos]) {
|
|
1369
|
+
makeTrans = true;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
else if (transColor[0] === indata[pxPos] && transColor[1] === indata[pxPos + 1] && transColor[2] === indata[pxPos + 2]) {
|
|
1373
|
+
makeTrans = true;
|
|
1374
|
+
}
|
|
1375
|
+
if (makeTrans) {
|
|
1376
|
+
for (var i = 0; i < 4; i++) {
|
|
1377
|
+
outdata[pxPos + i] = 0;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
pxPos += 4;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
function scaleDepth(indata, outdata, width, height, depth) {
|
|
1386
|
+
var maxOutSample = 255;
|
|
1387
|
+
var maxInSample = Math.pow(2, depth) - 1;
|
|
1388
|
+
var pxPos = 0;
|
|
1389
|
+
|
|
1390
|
+
for (var y = 0; y < height; y++) {
|
|
1391
|
+
for (var x = 0; x < width; x++) {
|
|
1392
|
+
for (var i = 0; i < 4; i++) {
|
|
1393
|
+
outdata[pxPos + i] = Math.floor((indata[pxPos + i] * maxOutSample) / maxInSample + 0.5);
|
|
1394
|
+
}
|
|
1395
|
+
pxPos += 4;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
var formatNormaliser = function(indata, imageData) {
|
|
1401
|
+
|
|
1402
|
+
var depth = imageData.depth;
|
|
1403
|
+
var width = imageData.width;
|
|
1404
|
+
var height = imageData.height;
|
|
1405
|
+
var colorType = imageData.colorType;
|
|
1406
|
+
var transColor = imageData.transColor;
|
|
1407
|
+
var palette = imageData.palette;
|
|
1408
|
+
|
|
1409
|
+
var outdata = indata; // only different for 16 bits
|
|
1410
|
+
|
|
1411
|
+
if (colorType === 3) { // paletted
|
|
1412
|
+
dePalette(indata, outdata, width, height, palette);
|
|
1413
|
+
}
|
|
1414
|
+
else {
|
|
1415
|
+
if (transColor) {
|
|
1416
|
+
replaceTransparentColor(indata, outdata, width, height, transColor);
|
|
1417
|
+
}
|
|
1418
|
+
// if it needs scaling
|
|
1419
|
+
if (depth !== 8) {
|
|
1420
|
+
// if we need to change the buffer size
|
|
1421
|
+
if (depth === 16) {
|
|
1422
|
+
outdata = new Buffer(width * height * 4);
|
|
1423
|
+
}
|
|
1424
|
+
scaleDepth(indata, outdata, width, height, depth);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
return outdata;
|
|
1428
|
+
};
|
|
1429
|
+
|
|
1430
|
+
var parserAsync = createCommonjsModule(function (module) {
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
var ParserAsync = module.exports = function(options) {
|
|
1441
|
+
chunkstream.call(this);
|
|
1442
|
+
|
|
1443
|
+
this._parser = new parser(options, {
|
|
1444
|
+
read: this.read.bind(this),
|
|
1445
|
+
error: this._handleError.bind(this),
|
|
1446
|
+
metadata: this._handleMetaData.bind(this),
|
|
1447
|
+
gamma: this.emit.bind(this, 'gamma'),
|
|
1448
|
+
palette: this._handlePalette.bind(this),
|
|
1449
|
+
transColor: this._handleTransColor.bind(this),
|
|
1450
|
+
finished: this._finished.bind(this),
|
|
1451
|
+
inflateData: this._inflateData.bind(this),
|
|
1452
|
+
simpleTransparency: this._simpleTransparency.bind(this),
|
|
1453
|
+
headersFinished: this._headersFinished.bind(this)
|
|
1454
|
+
});
|
|
1455
|
+
this._options = options;
|
|
1456
|
+
this.writable = true;
|
|
1457
|
+
|
|
1458
|
+
this._parser.start();
|
|
1459
|
+
};
|
|
1460
|
+
util__default['default'].inherits(ParserAsync, chunkstream);
|
|
1461
|
+
|
|
1462
|
+
|
|
1463
|
+
ParserAsync.prototype._handleError = function(err) {
|
|
1464
|
+
|
|
1465
|
+
this.emit('error', err);
|
|
1466
|
+
|
|
1467
|
+
this.writable = false;
|
|
1468
|
+
|
|
1469
|
+
this.destroy();
|
|
1470
|
+
|
|
1471
|
+
if (this._inflate && this._inflate.destroy) {
|
|
1472
|
+
this._inflate.destroy();
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
if (this._filter) {
|
|
1476
|
+
this._filter.destroy();
|
|
1477
|
+
// For backward compatibility with Node 7 and below.
|
|
1478
|
+
// Suppress errors due to _inflate calling write() even after
|
|
1479
|
+
// it's destroy()'ed.
|
|
1480
|
+
this._filter.on('error', function() {});
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
this.errord = true;
|
|
1484
|
+
};
|
|
1485
|
+
|
|
1486
|
+
ParserAsync.prototype._inflateData = function(data) {
|
|
1487
|
+
if (!this._inflate) {
|
|
1488
|
+
if (this._bitmapInfo.interlace) {
|
|
1489
|
+
this._inflate = zlib__default['default'].createInflate();
|
|
1490
|
+
|
|
1491
|
+
this._inflate.on('error', this.emit.bind(this, 'error'));
|
|
1492
|
+
this._filter.on('complete', this._complete.bind(this));
|
|
1493
|
+
|
|
1494
|
+
this._inflate.pipe(this._filter);
|
|
1495
|
+
}
|
|
1496
|
+
else {
|
|
1497
|
+
var rowSize = ((this._bitmapInfo.width * this._bitmapInfo.bpp * this._bitmapInfo.depth + 7) >> 3) + 1;
|
|
1498
|
+
var imageSize = rowSize * this._bitmapInfo.height;
|
|
1499
|
+
var chunkSize = Math.max(imageSize, zlib__default['default'].Z_MIN_CHUNK);
|
|
1500
|
+
|
|
1501
|
+
this._inflate = zlib__default['default'].createInflate({ chunkSize: chunkSize });
|
|
1502
|
+
var leftToInflate = imageSize;
|
|
1503
|
+
|
|
1504
|
+
var emitError = this.emit.bind(this, 'error');
|
|
1505
|
+
this._inflate.on('error', function(err) {
|
|
1506
|
+
if (!leftToInflate) {
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
emitError(err);
|
|
1511
|
+
});
|
|
1512
|
+
this._filter.on('complete', this._complete.bind(this));
|
|
1513
|
+
|
|
1514
|
+
var filterWrite = this._filter.write.bind(this._filter);
|
|
1515
|
+
this._inflate.on('data', function(chunk) {
|
|
1516
|
+
if (!leftToInflate) {
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
if (chunk.length > leftToInflate) {
|
|
1521
|
+
chunk = chunk.slice(0, leftToInflate);
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
leftToInflate -= chunk.length;
|
|
1525
|
+
|
|
1526
|
+
filterWrite(chunk);
|
|
1527
|
+
});
|
|
1528
|
+
|
|
1529
|
+
this._inflate.on('end', this._filter.end.bind(this._filter));
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
this._inflate.write(data);
|
|
1533
|
+
};
|
|
1534
|
+
|
|
1535
|
+
ParserAsync.prototype._handleMetaData = function(metaData) {
|
|
1536
|
+
this._metaData = metaData;
|
|
1537
|
+
this._bitmapInfo = Object.create(metaData);
|
|
1538
|
+
|
|
1539
|
+
this._filter = new filterParseAsync(this._bitmapInfo);
|
|
1540
|
+
};
|
|
1541
|
+
|
|
1542
|
+
ParserAsync.prototype._handleTransColor = function(transColor) {
|
|
1543
|
+
this._bitmapInfo.transColor = transColor;
|
|
1544
|
+
};
|
|
1545
|
+
|
|
1546
|
+
ParserAsync.prototype._handlePalette = function(palette) {
|
|
1547
|
+
this._bitmapInfo.palette = palette;
|
|
1548
|
+
};
|
|
1549
|
+
|
|
1550
|
+
ParserAsync.prototype._simpleTransparency = function() {
|
|
1551
|
+
this._metaData.alpha = true;
|
|
1552
|
+
};
|
|
1553
|
+
|
|
1554
|
+
ParserAsync.prototype._headersFinished = function() {
|
|
1555
|
+
// Up until this point, we don't know if we have a tRNS chunk (alpha)
|
|
1556
|
+
// so we can't emit metadata any earlier
|
|
1557
|
+
this.emit('metadata', this._metaData);
|
|
1558
|
+
};
|
|
1559
|
+
|
|
1560
|
+
ParserAsync.prototype._finished = function() {
|
|
1561
|
+
if (this.errord) {
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
if (!this._inflate) {
|
|
1566
|
+
this.emit('error', 'No Inflate block');
|
|
1567
|
+
}
|
|
1568
|
+
else {
|
|
1569
|
+
// no more data to inflate
|
|
1570
|
+
this._inflate.end();
|
|
1571
|
+
}
|
|
1572
|
+
this.destroySoon();
|
|
1573
|
+
};
|
|
1574
|
+
|
|
1575
|
+
ParserAsync.prototype._complete = function(filteredData) {
|
|
1576
|
+
|
|
1577
|
+
if (this.errord) {
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
try {
|
|
1582
|
+
var bitmapData = bitmapper.dataToBitMap(filteredData, this._bitmapInfo);
|
|
1583
|
+
|
|
1584
|
+
var normalisedBitmapData = formatNormaliser(bitmapData, this._bitmapInfo);
|
|
1585
|
+
bitmapData = null;
|
|
1586
|
+
}
|
|
1587
|
+
catch (ex) {
|
|
1588
|
+
this._handleError(ex);
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
this.emit('parsed', normalisedBitmapData);
|
|
1593
|
+
};
|
|
1594
|
+
});
|
|
1595
|
+
|
|
1596
|
+
var bitpacker = function(dataIn, width, height, options) {
|
|
1597
|
+
var outHasAlpha = [constants.COLORTYPE_COLOR_ALPHA, constants.COLORTYPE_ALPHA].indexOf(options.colorType) !== -1;
|
|
1598
|
+
if (options.colorType === options.inputColorType) {
|
|
1599
|
+
var bigEndian = (function() {
|
|
1600
|
+
var buffer = new ArrayBuffer(2);
|
|
1601
|
+
new DataView(buffer).setInt16(0, 256, true /* littleEndian */);
|
|
1602
|
+
// Int16Array uses the platform's endianness.
|
|
1603
|
+
return new Int16Array(buffer)[0] !== 256;
|
|
1604
|
+
})();
|
|
1605
|
+
// If no need to convert to grayscale and alpha is present/absent in both, take a fast route
|
|
1606
|
+
if (options.bitDepth === 8 || (options.bitDepth === 16 && bigEndian)) {
|
|
1607
|
+
return dataIn;
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
// map to a UInt16 array if data is 16bit, fix endianness below
|
|
1612
|
+
var data = options.bitDepth !== 16 ? dataIn : new Uint16Array(dataIn.buffer);
|
|
1613
|
+
|
|
1614
|
+
var maxValue = 255;
|
|
1615
|
+
var inBpp = constants.COLORTYPE_TO_BPP_MAP[options.inputColorType];
|
|
1616
|
+
if (inBpp === 4 && !options.inputHasAlpha) {
|
|
1617
|
+
inBpp = 3;
|
|
1618
|
+
}
|
|
1619
|
+
var outBpp = constants.COLORTYPE_TO_BPP_MAP[options.colorType];
|
|
1620
|
+
if (options.bitDepth === 16) {
|
|
1621
|
+
maxValue = 65535;
|
|
1622
|
+
outBpp *= 2;
|
|
1623
|
+
}
|
|
1624
|
+
var outData = new Buffer(width * height * outBpp);
|
|
1625
|
+
|
|
1626
|
+
var inIndex = 0;
|
|
1627
|
+
var outIndex = 0;
|
|
1628
|
+
|
|
1629
|
+
var bgColor = options.bgColor || {};
|
|
1630
|
+
if (bgColor.red === undefined) {
|
|
1631
|
+
bgColor.red = maxValue;
|
|
1632
|
+
}
|
|
1633
|
+
if (bgColor.green === undefined) {
|
|
1634
|
+
bgColor.green = maxValue;
|
|
1635
|
+
}
|
|
1636
|
+
if (bgColor.blue === undefined) {
|
|
1637
|
+
bgColor.blue = maxValue;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
function getRGBA() {
|
|
1641
|
+
var red;
|
|
1642
|
+
var green;
|
|
1643
|
+
var blue;
|
|
1644
|
+
var alpha = maxValue;
|
|
1645
|
+
switch (options.inputColorType) {
|
|
1646
|
+
case constants.COLORTYPE_COLOR_ALPHA:
|
|
1647
|
+
alpha = data[inIndex + 3];
|
|
1648
|
+
red = data[inIndex];
|
|
1649
|
+
green = data[inIndex + 1];
|
|
1650
|
+
blue = data[inIndex + 2];
|
|
1651
|
+
break;
|
|
1652
|
+
case constants.COLORTYPE_COLOR:
|
|
1653
|
+
red = data[inIndex];
|
|
1654
|
+
green = data[inIndex + 1];
|
|
1655
|
+
blue = data[inIndex + 2];
|
|
1656
|
+
break;
|
|
1657
|
+
case constants.COLORTYPE_ALPHA:
|
|
1658
|
+
alpha = data[inIndex + 1];
|
|
1659
|
+
red = data[inIndex];
|
|
1660
|
+
green = red;
|
|
1661
|
+
blue = red;
|
|
1662
|
+
break;
|
|
1663
|
+
case constants.COLORTYPE_GRAYSCALE:
|
|
1664
|
+
red = data[inIndex];
|
|
1665
|
+
green = red;
|
|
1666
|
+
blue = red;
|
|
1667
|
+
break;
|
|
1668
|
+
default:
|
|
1669
|
+
throw new Error('input color type:' + options.inputColorType + ' is not supported at present');
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
if (options.inputHasAlpha) {
|
|
1673
|
+
if (!outHasAlpha) {
|
|
1674
|
+
alpha /= maxValue;
|
|
1675
|
+
red = Math.min(Math.max(Math.round((1 - alpha) * bgColor.red + alpha * red), 0), maxValue);
|
|
1676
|
+
green = Math.min(Math.max(Math.round((1 - alpha) * bgColor.green + alpha * green), 0), maxValue);
|
|
1677
|
+
blue = Math.min(Math.max(Math.round((1 - alpha) * bgColor.blue + alpha * blue), 0), maxValue);
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
return { red: red, green: green, blue: blue, alpha: alpha };
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
for (var y = 0; y < height; y++) {
|
|
1684
|
+
for (var x = 0; x < width; x++) {
|
|
1685
|
+
var rgba = getRGBA();
|
|
1686
|
+
|
|
1687
|
+
switch (options.colorType) {
|
|
1688
|
+
case constants.COLORTYPE_COLOR_ALPHA:
|
|
1689
|
+
case constants.COLORTYPE_COLOR:
|
|
1690
|
+
if (options.bitDepth === 8) {
|
|
1691
|
+
outData[outIndex] = rgba.red;
|
|
1692
|
+
outData[outIndex + 1] = rgba.green;
|
|
1693
|
+
outData[outIndex + 2] = rgba.blue;
|
|
1694
|
+
if (outHasAlpha) {
|
|
1695
|
+
outData[outIndex + 3] = rgba.alpha;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
else {
|
|
1699
|
+
outData.writeUInt16BE(rgba.red, outIndex);
|
|
1700
|
+
outData.writeUInt16BE(rgba.green, outIndex + 2);
|
|
1701
|
+
outData.writeUInt16BE(rgba.blue, outIndex + 4);
|
|
1702
|
+
if (outHasAlpha) {
|
|
1703
|
+
outData.writeUInt16BE(rgba.alpha, outIndex + 6);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
break;
|
|
1707
|
+
case constants.COLORTYPE_ALPHA:
|
|
1708
|
+
case constants.COLORTYPE_GRAYSCALE:
|
|
1709
|
+
// Convert to grayscale and alpha
|
|
1710
|
+
var grayscale = (rgba.red + rgba.green + rgba.blue) / 3;
|
|
1711
|
+
if (options.bitDepth === 8) {
|
|
1712
|
+
outData[outIndex] = grayscale;
|
|
1713
|
+
if (outHasAlpha) {
|
|
1714
|
+
outData[outIndex + 1] = rgba.alpha;
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
else {
|
|
1718
|
+
outData.writeUInt16BE(grayscale, outIndex);
|
|
1719
|
+
if (outHasAlpha) {
|
|
1720
|
+
outData.writeUInt16BE(rgba.alpha, outIndex + 2);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
break;
|
|
1724
|
+
default:
|
|
1725
|
+
throw new Error('unrecognised color Type ' + options.colorType);
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
inIndex += inBpp;
|
|
1729
|
+
outIndex += outBpp;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
return outData;
|
|
1734
|
+
};
|
|
1735
|
+
|
|
1736
|
+
function filterNone(pxData, pxPos, byteWidth, rawData, rawPos) {
|
|
1737
|
+
|
|
1738
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
1739
|
+
rawData[rawPos + x] = pxData[pxPos + x];
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
function filterSumNone(pxData, pxPos, byteWidth) {
|
|
1744
|
+
|
|
1745
|
+
var sum = 0;
|
|
1746
|
+
var length = pxPos + byteWidth;
|
|
1747
|
+
|
|
1748
|
+
for (var i = pxPos; i < length; i++) {
|
|
1749
|
+
sum += Math.abs(pxData[i]);
|
|
1750
|
+
}
|
|
1751
|
+
return sum;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
function filterSub(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
|
|
1755
|
+
|
|
1756
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
1757
|
+
|
|
1758
|
+
var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
1759
|
+
var val = pxData[pxPos + x] - left;
|
|
1760
|
+
|
|
1761
|
+
rawData[rawPos + x] = val;
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
function filterSumSub(pxData, pxPos, byteWidth, bpp) {
|
|
1766
|
+
|
|
1767
|
+
var sum = 0;
|
|
1768
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
1769
|
+
|
|
1770
|
+
var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
1771
|
+
var val = pxData[pxPos + x] - left;
|
|
1772
|
+
|
|
1773
|
+
sum += Math.abs(val);
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
return sum;
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
function filterUp(pxData, pxPos, byteWidth, rawData, rawPos) {
|
|
1780
|
+
|
|
1781
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
1782
|
+
|
|
1783
|
+
var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
1784
|
+
var val = pxData[pxPos + x] - up;
|
|
1785
|
+
|
|
1786
|
+
rawData[rawPos + x] = val;
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
function filterSumUp(pxData, pxPos, byteWidth) {
|
|
1791
|
+
|
|
1792
|
+
var sum = 0;
|
|
1793
|
+
var length = pxPos + byteWidth;
|
|
1794
|
+
for (var x = pxPos; x < length; x++) {
|
|
1795
|
+
|
|
1796
|
+
var up = pxPos > 0 ? pxData[x - byteWidth] : 0;
|
|
1797
|
+
var val = pxData[x] - up;
|
|
1798
|
+
|
|
1799
|
+
sum += Math.abs(val);
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
return sum;
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
function filterAvg(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
|
|
1806
|
+
|
|
1807
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
1808
|
+
|
|
1809
|
+
var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
1810
|
+
var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
1811
|
+
var val = pxData[pxPos + x] - ((left + up) >> 1);
|
|
1812
|
+
|
|
1813
|
+
rawData[rawPos + x] = val;
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
function filterSumAvg(pxData, pxPos, byteWidth, bpp) {
|
|
1818
|
+
|
|
1819
|
+
var sum = 0;
|
|
1820
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
1821
|
+
|
|
1822
|
+
var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
1823
|
+
var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
1824
|
+
var val = pxData[pxPos + x] - ((left + up) >> 1);
|
|
1825
|
+
|
|
1826
|
+
sum += Math.abs(val);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
return sum;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
function filterPaeth(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
|
|
1833
|
+
|
|
1834
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
1835
|
+
|
|
1836
|
+
var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
1837
|
+
var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
1838
|
+
var upleft = pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
|
|
1839
|
+
var val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
|
|
1840
|
+
|
|
1841
|
+
rawData[rawPos + x] = val;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
function filterSumPaeth(pxData, pxPos, byteWidth, bpp) {
|
|
1846
|
+
var sum = 0;
|
|
1847
|
+
for (var x = 0; x < byteWidth; x++) {
|
|
1848
|
+
|
|
1849
|
+
var left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
|
|
1850
|
+
var up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
|
|
1851
|
+
var upleft = pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
|
|
1852
|
+
var val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
|
|
1853
|
+
|
|
1854
|
+
sum += Math.abs(val);
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
return sum;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
var filters = {
|
|
1861
|
+
0: filterNone,
|
|
1862
|
+
1: filterSub,
|
|
1863
|
+
2: filterUp,
|
|
1864
|
+
3: filterAvg,
|
|
1865
|
+
4: filterPaeth
|
|
1866
|
+
};
|
|
1867
|
+
|
|
1868
|
+
var filterSums = {
|
|
1869
|
+
0: filterSumNone,
|
|
1870
|
+
1: filterSumSub,
|
|
1871
|
+
2: filterSumUp,
|
|
1872
|
+
3: filterSumAvg,
|
|
1873
|
+
4: filterSumPaeth
|
|
1874
|
+
};
|
|
1875
|
+
|
|
1876
|
+
var filterPack = function(pxData, width, height, options, bpp) {
|
|
1877
|
+
|
|
1878
|
+
var filterTypes;
|
|
1879
|
+
if (!('filterType' in options) || options.filterType === -1) {
|
|
1880
|
+
filterTypes = [0, 1, 2, 3, 4];
|
|
1881
|
+
}
|
|
1882
|
+
else if (typeof options.filterType === 'number') {
|
|
1883
|
+
filterTypes = [options.filterType];
|
|
1884
|
+
}
|
|
1885
|
+
else {
|
|
1886
|
+
throw new Error('unrecognised filter types');
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
if (options.bitDepth === 16) {
|
|
1890
|
+
bpp *= 2;
|
|
1891
|
+
}
|
|
1892
|
+
var byteWidth = width * bpp;
|
|
1893
|
+
var rawPos = 0;
|
|
1894
|
+
var pxPos = 0;
|
|
1895
|
+
var rawData = new Buffer((byteWidth + 1) * height);
|
|
1896
|
+
|
|
1897
|
+
var sel = filterTypes[0];
|
|
1898
|
+
|
|
1899
|
+
for (var y = 0; y < height; y++) {
|
|
1900
|
+
|
|
1901
|
+
if (filterTypes.length > 1) {
|
|
1902
|
+
// find best filter for this line (with lowest sum of values)
|
|
1903
|
+
var min = Infinity;
|
|
1904
|
+
|
|
1905
|
+
for (var i = 0; i < filterTypes.length; i++) {
|
|
1906
|
+
var sum = filterSums[filterTypes[i]](pxData, pxPos, byteWidth, bpp);
|
|
1907
|
+
if (sum < min) {
|
|
1908
|
+
sel = filterTypes[i];
|
|
1909
|
+
min = sum;
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
rawData[rawPos] = sel;
|
|
1915
|
+
rawPos++;
|
|
1916
|
+
filters[sel](pxData, pxPos, byteWidth, rawData, rawPos, bpp);
|
|
1917
|
+
rawPos += byteWidth;
|
|
1918
|
+
pxPos += byteWidth;
|
|
1919
|
+
}
|
|
1920
|
+
return rawData;
|
|
1921
|
+
};
|
|
1922
|
+
|
|
1923
|
+
var packer = createCommonjsModule(function (module) {
|
|
1924
|
+
|
|
1925
|
+
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
var Packer = module.exports = function(options) {
|
|
1932
|
+
this._options = options;
|
|
1933
|
+
|
|
1934
|
+
options.deflateChunkSize = options.deflateChunkSize || 32 * 1024;
|
|
1935
|
+
options.deflateLevel = options.deflateLevel != null ? options.deflateLevel : 9;
|
|
1936
|
+
options.deflateStrategy = options.deflateStrategy != null ? options.deflateStrategy : 3;
|
|
1937
|
+
options.inputHasAlpha = options.inputHasAlpha != null ? options.inputHasAlpha : true;
|
|
1938
|
+
options.deflateFactory = options.deflateFactory || zlib__default['default'].createDeflate;
|
|
1939
|
+
options.bitDepth = options.bitDepth || 8;
|
|
1940
|
+
// This is outputColorType
|
|
1941
|
+
options.colorType = (typeof options.colorType === 'number') ? options.colorType : constants.COLORTYPE_COLOR_ALPHA;
|
|
1942
|
+
options.inputColorType = (typeof options.inputColorType === 'number') ? options.inputColorType : constants.COLORTYPE_COLOR_ALPHA;
|
|
1943
|
+
|
|
1944
|
+
if ([
|
|
1945
|
+
constants.COLORTYPE_GRAYSCALE,
|
|
1946
|
+
constants.COLORTYPE_COLOR,
|
|
1947
|
+
constants.COLORTYPE_COLOR_ALPHA,
|
|
1948
|
+
constants.COLORTYPE_ALPHA
|
|
1949
|
+
].indexOf(options.colorType) === -1) {
|
|
1950
|
+
throw new Error('option color type:' + options.colorType + ' is not supported at present');
|
|
1951
|
+
}
|
|
1952
|
+
if ([
|
|
1953
|
+
constants.COLORTYPE_GRAYSCALE,
|
|
1954
|
+
constants.COLORTYPE_COLOR,
|
|
1955
|
+
constants.COLORTYPE_COLOR_ALPHA,
|
|
1956
|
+
constants.COLORTYPE_ALPHA
|
|
1957
|
+
].indexOf(options.inputColorType) === -1) {
|
|
1958
|
+
throw new Error('option input color type:' + options.inputColorType + ' is not supported at present');
|
|
1959
|
+
}
|
|
1960
|
+
if (options.bitDepth !== 8 && options.bitDepth !== 16) {
|
|
1961
|
+
throw new Error('option bit depth:' + options.bitDepth + ' is not supported at present');
|
|
1962
|
+
}
|
|
1963
|
+
};
|
|
1964
|
+
|
|
1965
|
+
Packer.prototype.getDeflateOptions = function() {
|
|
1966
|
+
return {
|
|
1967
|
+
chunkSize: this._options.deflateChunkSize,
|
|
1968
|
+
level: this._options.deflateLevel,
|
|
1969
|
+
strategy: this._options.deflateStrategy
|
|
1970
|
+
};
|
|
1971
|
+
};
|
|
1972
|
+
|
|
1973
|
+
Packer.prototype.createDeflate = function() {
|
|
1974
|
+
return this._options.deflateFactory(this.getDeflateOptions());
|
|
1975
|
+
};
|
|
1976
|
+
|
|
1977
|
+
Packer.prototype.filterData = function(data, width, height) {
|
|
1978
|
+
// convert to correct format for filtering (e.g. right bpp and bit depth)
|
|
1979
|
+
var packedData = bitpacker(data, width, height, this._options);
|
|
1980
|
+
|
|
1981
|
+
// filter pixel data
|
|
1982
|
+
var bpp = constants.COLORTYPE_TO_BPP_MAP[this._options.colorType];
|
|
1983
|
+
var filteredData = filterPack(packedData, width, height, this._options, bpp);
|
|
1984
|
+
return filteredData;
|
|
1985
|
+
};
|
|
1986
|
+
|
|
1987
|
+
Packer.prototype._packChunk = function(type, data) {
|
|
1988
|
+
|
|
1989
|
+
var len = (data ? data.length : 0);
|
|
1990
|
+
var buf = new Buffer(len + 12);
|
|
1991
|
+
|
|
1992
|
+
buf.writeUInt32BE(len, 0);
|
|
1993
|
+
buf.writeUInt32BE(type, 4);
|
|
1994
|
+
|
|
1995
|
+
if (data) {
|
|
1996
|
+
data.copy(buf, 8);
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
buf.writeInt32BE(crc.crc32(buf.slice(4, buf.length - 4)), buf.length - 4);
|
|
2000
|
+
return buf;
|
|
2001
|
+
};
|
|
2002
|
+
|
|
2003
|
+
Packer.prototype.packGAMA = function(gamma) {
|
|
2004
|
+
var buf = new Buffer(4);
|
|
2005
|
+
buf.writeUInt32BE(Math.floor(gamma * constants.GAMMA_DIVISION), 0);
|
|
2006
|
+
return this._packChunk(constants.TYPE_gAMA, buf);
|
|
2007
|
+
};
|
|
2008
|
+
|
|
2009
|
+
Packer.prototype.packIHDR = function(width, height) {
|
|
2010
|
+
|
|
2011
|
+
var buf = new Buffer(13);
|
|
2012
|
+
buf.writeUInt32BE(width, 0);
|
|
2013
|
+
buf.writeUInt32BE(height, 4);
|
|
2014
|
+
buf[8] = this._options.bitDepth; // Bit depth
|
|
2015
|
+
buf[9] = this._options.colorType; // colorType
|
|
2016
|
+
buf[10] = 0; // compression
|
|
2017
|
+
buf[11] = 0; // filter
|
|
2018
|
+
buf[12] = 0; // interlace
|
|
2019
|
+
|
|
2020
|
+
return this._packChunk(constants.TYPE_IHDR, buf);
|
|
2021
|
+
};
|
|
2022
|
+
|
|
2023
|
+
Packer.prototype.packIDAT = function(data) {
|
|
2024
|
+
return this._packChunk(constants.TYPE_IDAT, data);
|
|
2025
|
+
};
|
|
2026
|
+
|
|
2027
|
+
Packer.prototype.packIEND = function() {
|
|
2028
|
+
return this._packChunk(constants.TYPE_IEND, null);
|
|
2029
|
+
};
|
|
2030
|
+
});
|
|
2031
|
+
|
|
2032
|
+
var packerAsync = createCommonjsModule(function (module) {
|
|
2033
|
+
|
|
2034
|
+
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
|
|
2038
|
+
|
|
2039
|
+
var PackerAsync = module.exports = function(opt) {
|
|
2040
|
+
Stream__default['default'].call(this);
|
|
2041
|
+
|
|
2042
|
+
var options = opt || {};
|
|
2043
|
+
|
|
2044
|
+
this._packer = new packer(options);
|
|
2045
|
+
this._deflate = this._packer.createDeflate();
|
|
2046
|
+
|
|
2047
|
+
this.readable = true;
|
|
2048
|
+
};
|
|
2049
|
+
util__default['default'].inherits(PackerAsync, Stream__default['default']);
|
|
2050
|
+
|
|
2051
|
+
|
|
2052
|
+
PackerAsync.prototype.pack = function(data, width, height, gamma) {
|
|
2053
|
+
// Signature
|
|
2054
|
+
this.emit('data', new Buffer(constants.PNG_SIGNATURE));
|
|
2055
|
+
this.emit('data', this._packer.packIHDR(width, height));
|
|
2056
|
+
|
|
2057
|
+
if (gamma) {
|
|
2058
|
+
this.emit('data', this._packer.packGAMA(gamma));
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
var filteredData = this._packer.filterData(data, width, height);
|
|
2062
|
+
|
|
2063
|
+
// compress it
|
|
2064
|
+
this._deflate.on('error', this.emit.bind(this, 'error'));
|
|
2065
|
+
|
|
2066
|
+
this._deflate.on('data', function(compressedData) {
|
|
2067
|
+
this.emit('data', this._packer.packIDAT(compressedData));
|
|
2068
|
+
}.bind(this));
|
|
2069
|
+
|
|
2070
|
+
this._deflate.on('end', function() {
|
|
2071
|
+
this.emit('data', this._packer.packIEND());
|
|
2072
|
+
this.emit('end');
|
|
2073
|
+
}.bind(this));
|
|
2074
|
+
|
|
2075
|
+
this._deflate.end(filteredData);
|
|
2076
|
+
};
|
|
2077
|
+
});
|
|
2078
|
+
|
|
2079
|
+
var syncInflate = createCommonjsModule(function (module, exports) {
|
|
2080
|
+
|
|
2081
|
+
var assert = require$$0__default['default'].ok;
|
|
2082
|
+
|
|
2083
|
+
|
|
2084
|
+
|
|
2085
|
+
var kMaxLength = require$$1__default['default'].kMaxLength;
|
|
2086
|
+
|
|
2087
|
+
function Inflate(opts) {
|
|
2088
|
+
if (!(this instanceof Inflate)) {
|
|
2089
|
+
return new Inflate(opts);
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
if (opts && opts.chunkSize < zlib__default['default'].Z_MIN_CHUNK) {
|
|
2093
|
+
opts.chunkSize = zlib__default['default'].Z_MIN_CHUNK;
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
zlib__default['default'].Inflate.call(this, opts);
|
|
2097
|
+
|
|
2098
|
+
// Node 8 --> 9 compatibility check
|
|
2099
|
+
this._offset = this._offset === undefined ? this._outOffset : this._offset;
|
|
2100
|
+
this._buffer = this._buffer || this._outBuffer;
|
|
2101
|
+
|
|
2102
|
+
if (opts && opts.maxLength != null) {
|
|
2103
|
+
this._maxLength = opts.maxLength;
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
function createInflate(opts) {
|
|
2108
|
+
return new Inflate(opts);
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
function _close(engine, callback) {
|
|
2112
|
+
if (callback) {
|
|
2113
|
+
process.nextTick(callback);
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
// Caller may invoke .close after a zlib error (which will null _handle).
|
|
2117
|
+
if (!engine._handle) {
|
|
2118
|
+
return;
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
engine._handle.close();
|
|
2122
|
+
engine._handle = null;
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
Inflate.prototype._processChunk = function(chunk, flushFlag, asyncCb) {
|
|
2126
|
+
if (typeof asyncCb === 'function') {
|
|
2127
|
+
return zlib__default['default'].Inflate._processChunk.call(this, chunk, flushFlag, asyncCb);
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
var self = this;
|
|
2131
|
+
|
|
2132
|
+
var availInBefore = chunk && chunk.length;
|
|
2133
|
+
var availOutBefore = this._chunkSize - this._offset;
|
|
2134
|
+
var leftToInflate = this._maxLength;
|
|
2135
|
+
var inOff = 0;
|
|
2136
|
+
|
|
2137
|
+
var buffers = [];
|
|
2138
|
+
var nread = 0;
|
|
2139
|
+
|
|
2140
|
+
var error;
|
|
2141
|
+
this.on('error', function(err) {
|
|
2142
|
+
error = err;
|
|
2143
|
+
});
|
|
2144
|
+
|
|
2145
|
+
function handleChunk(availInAfter, availOutAfter) {
|
|
2146
|
+
if (self._hadError) {
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
var have = availOutBefore - availOutAfter;
|
|
2151
|
+
assert(have >= 0, 'have should not go down');
|
|
2152
|
+
|
|
2153
|
+
if (have > 0) {
|
|
2154
|
+
var out = self._buffer.slice(self._offset, self._offset + have);
|
|
2155
|
+
self._offset += have;
|
|
2156
|
+
|
|
2157
|
+
if (out.length > leftToInflate) {
|
|
2158
|
+
out = out.slice(0, leftToInflate);
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
buffers.push(out);
|
|
2162
|
+
nread += out.length;
|
|
2163
|
+
leftToInflate -= out.length;
|
|
2164
|
+
|
|
2165
|
+
if (leftToInflate === 0) {
|
|
2166
|
+
return false;
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
if (availOutAfter === 0 || self._offset >= self._chunkSize) {
|
|
2171
|
+
availOutBefore = self._chunkSize;
|
|
2172
|
+
self._offset = 0;
|
|
2173
|
+
self._buffer = Buffer.allocUnsafe(self._chunkSize);
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
if (availOutAfter === 0) {
|
|
2177
|
+
inOff += (availInBefore - availInAfter);
|
|
2178
|
+
availInBefore = availInAfter;
|
|
2179
|
+
|
|
2180
|
+
return true;
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
return false;
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
assert(this._handle, 'zlib binding closed');
|
|
2187
|
+
do {
|
|
2188
|
+
var res = this._handle.writeSync(flushFlag,
|
|
2189
|
+
chunk, // in
|
|
2190
|
+
inOff, // in_off
|
|
2191
|
+
availInBefore, // in_len
|
|
2192
|
+
this._buffer, // out
|
|
2193
|
+
this._offset, //out_off
|
|
2194
|
+
availOutBefore); // out_len
|
|
2195
|
+
// Node 8 --> 9 compatibility check
|
|
2196
|
+
res = res || this._writeState;
|
|
2197
|
+
} while (!this._hadError && handleChunk(res[0], res[1]));
|
|
2198
|
+
|
|
2199
|
+
if (this._hadError) {
|
|
2200
|
+
throw error;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
if (nread >= kMaxLength) {
|
|
2204
|
+
_close(this);
|
|
2205
|
+
throw new RangeError('Cannot create final Buffer. It would be larger than 0x' + kMaxLength.toString(16) + ' bytes');
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
var buf = Buffer.concat(buffers, nread);
|
|
2209
|
+
_close(this);
|
|
2210
|
+
|
|
2211
|
+
return buf;
|
|
2212
|
+
};
|
|
2213
|
+
|
|
2214
|
+
util__default['default'].inherits(Inflate, zlib__default['default'].Inflate);
|
|
2215
|
+
|
|
2216
|
+
function zlibBufferSync(engine, buffer) {
|
|
2217
|
+
if (typeof buffer === 'string') {
|
|
2218
|
+
buffer = Buffer.from(buffer);
|
|
2219
|
+
}
|
|
2220
|
+
if (!(buffer instanceof Buffer)) {
|
|
2221
|
+
throw new TypeError('Not a string or buffer');
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
var flushFlag = engine._finishFlushFlag;
|
|
2225
|
+
if (flushFlag == null) {
|
|
2226
|
+
flushFlag = zlib__default['default'].Z_FINISH;
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
return engine._processChunk(buffer, flushFlag);
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
function inflateSync(buffer, opts) {
|
|
2233
|
+
return zlibBufferSync(new Inflate(opts), buffer);
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
module.exports = exports = inflateSync;
|
|
2237
|
+
exports.Inflate = Inflate;
|
|
2238
|
+
exports.createInflate = createInflate;
|
|
2239
|
+
exports.inflateSync = inflateSync;
|
|
2240
|
+
});
|
|
2241
|
+
|
|
2242
|
+
var syncReader = createCommonjsModule(function (module) {
|
|
2243
|
+
|
|
2244
|
+
var SyncReader = module.exports = function(buffer) {
|
|
2245
|
+
|
|
2246
|
+
this._buffer = buffer;
|
|
2247
|
+
this._reads = [];
|
|
2248
|
+
};
|
|
2249
|
+
|
|
2250
|
+
SyncReader.prototype.read = function(length, callback) {
|
|
2251
|
+
|
|
2252
|
+
this._reads.push({
|
|
2253
|
+
length: Math.abs(length), // if length < 0 then at most this length
|
|
2254
|
+
allowLess: length < 0,
|
|
2255
|
+
func: callback
|
|
2256
|
+
});
|
|
2257
|
+
};
|
|
2258
|
+
|
|
2259
|
+
SyncReader.prototype.process = function() {
|
|
2260
|
+
|
|
2261
|
+
// as long as there is any data and read requests
|
|
2262
|
+
while (this._reads.length > 0 && this._buffer.length) {
|
|
2263
|
+
|
|
2264
|
+
var read = this._reads[0];
|
|
2265
|
+
|
|
2266
|
+
if (this._buffer.length && (this._buffer.length >= read.length || read.allowLess)) {
|
|
2267
|
+
|
|
2268
|
+
// ok there is any data so that we can satisfy this request
|
|
2269
|
+
this._reads.shift(); // == read
|
|
2270
|
+
|
|
2271
|
+
var buf = this._buffer;
|
|
2272
|
+
|
|
2273
|
+
this._buffer = buf.slice(read.length);
|
|
2274
|
+
|
|
2275
|
+
read.func.call(this, buf.slice(0, read.length));
|
|
2276
|
+
|
|
2277
|
+
}
|
|
2278
|
+
else {
|
|
2279
|
+
break;
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
if (this._reads.length > 0) {
|
|
2285
|
+
return new Error('There are some read requests waitng on finished stream');
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
if (this._buffer.length > 0) {
|
|
2289
|
+
return new Error('unrecognised content at end of stream');
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
};
|
|
2293
|
+
});
|
|
2294
|
+
|
|
2295
|
+
var process_1 = function(inBuffer, bitmapInfo) {
|
|
2296
|
+
|
|
2297
|
+
var outBuffers = [];
|
|
2298
|
+
var reader = new syncReader(inBuffer);
|
|
2299
|
+
var filter = new filterParse(bitmapInfo, {
|
|
2300
|
+
read: reader.read.bind(reader),
|
|
2301
|
+
write: function(bufferPart) {
|
|
2302
|
+
outBuffers.push(bufferPart);
|
|
2303
|
+
},
|
|
2304
|
+
complete: function() {
|
|
2305
|
+
}
|
|
2306
|
+
});
|
|
2307
|
+
|
|
2308
|
+
filter.start();
|
|
2309
|
+
reader.process();
|
|
2310
|
+
|
|
2311
|
+
return Buffer.concat(outBuffers);
|
|
2312
|
+
};
|
|
2313
|
+
|
|
2314
|
+
var filterParseSync = {
|
|
2315
|
+
process: process_1
|
|
2316
|
+
};
|
|
2317
|
+
|
|
2318
|
+
var hasSyncZlib$1 = true;
|
|
2319
|
+
|
|
2320
|
+
|
|
2321
|
+
if (!zlib__default['default'].deflateSync) {
|
|
2322
|
+
hasSyncZlib$1 = false;
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
|
|
2326
|
+
|
|
2327
|
+
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
|
|
2331
|
+
var parserSync = function(buffer, options) {
|
|
2332
|
+
|
|
2333
|
+
if (!hasSyncZlib$1) {
|
|
2334
|
+
throw new Error('To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0');
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
var err;
|
|
2338
|
+
function handleError(_err_) {
|
|
2339
|
+
err = _err_;
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
var metaData;
|
|
2343
|
+
function handleMetaData(_metaData_) {
|
|
2344
|
+
metaData = _metaData_;
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
function handleTransColor(transColor) {
|
|
2348
|
+
metaData.transColor = transColor;
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
function handlePalette(palette) {
|
|
2352
|
+
metaData.palette = palette;
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
function handleSimpleTransparency() {
|
|
2356
|
+
metaData.alpha = true;
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
var gamma;
|
|
2360
|
+
function handleGamma(_gamma_) {
|
|
2361
|
+
gamma = _gamma_;
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
var inflateDataList = [];
|
|
2365
|
+
function handleInflateData(inflatedData) {
|
|
2366
|
+
inflateDataList.push(inflatedData);
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
var reader = new syncReader(buffer);
|
|
2370
|
+
|
|
2371
|
+
var parser$1 = new parser(options, {
|
|
2372
|
+
read: reader.read.bind(reader),
|
|
2373
|
+
error: handleError,
|
|
2374
|
+
metadata: handleMetaData,
|
|
2375
|
+
gamma: handleGamma,
|
|
2376
|
+
palette: handlePalette,
|
|
2377
|
+
transColor: handleTransColor,
|
|
2378
|
+
inflateData: handleInflateData,
|
|
2379
|
+
simpleTransparency: handleSimpleTransparency
|
|
2380
|
+
});
|
|
2381
|
+
|
|
2382
|
+
parser$1.start();
|
|
2383
|
+
reader.process();
|
|
2384
|
+
|
|
2385
|
+
if (err) {
|
|
2386
|
+
throw err;
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
//join together the inflate datas
|
|
2390
|
+
var inflateData = Buffer.concat(inflateDataList);
|
|
2391
|
+
inflateDataList.length = 0;
|
|
2392
|
+
|
|
2393
|
+
var inflatedData;
|
|
2394
|
+
if (metaData.interlace) {
|
|
2395
|
+
inflatedData = zlib__default['default'].inflateSync(inflateData);
|
|
2396
|
+
}
|
|
2397
|
+
else {
|
|
2398
|
+
var rowSize = ((metaData.width * metaData.bpp * metaData.depth + 7) >> 3) + 1;
|
|
2399
|
+
var imageSize = rowSize * metaData.height;
|
|
2400
|
+
inflatedData = syncInflate(inflateData, { chunkSize: imageSize, maxLength: imageSize });
|
|
2401
|
+
}
|
|
2402
|
+
inflateData = null;
|
|
2403
|
+
|
|
2404
|
+
if (!inflatedData || !inflatedData.length) {
|
|
2405
|
+
throw new Error('bad png - invalid inflate data response');
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
var unfilteredData = filterParseSync.process(inflatedData, metaData);
|
|
2409
|
+
inflateData = null;
|
|
2410
|
+
|
|
2411
|
+
var bitmapData = bitmapper.dataToBitMap(unfilteredData, metaData);
|
|
2412
|
+
unfilteredData = null;
|
|
2413
|
+
|
|
2414
|
+
var normalisedBitmapData = formatNormaliser(bitmapData, metaData);
|
|
2415
|
+
|
|
2416
|
+
metaData.data = normalisedBitmapData;
|
|
2417
|
+
metaData.gamma = gamma || 0;
|
|
2418
|
+
|
|
2419
|
+
return metaData;
|
|
2420
|
+
};
|
|
2421
|
+
|
|
2422
|
+
var hasSyncZlib = true;
|
|
2423
|
+
|
|
2424
|
+
if (!zlib__default['default'].deflateSync) {
|
|
2425
|
+
hasSyncZlib = false;
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
|
|
2429
|
+
|
|
2430
|
+
var packerSync = function(metaData, opt) {
|
|
2431
|
+
|
|
2432
|
+
if (!hasSyncZlib) {
|
|
2433
|
+
throw new Error('To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0');
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
var options = opt || {};
|
|
2437
|
+
|
|
2438
|
+
var packer$1 = new packer(options);
|
|
2439
|
+
|
|
2440
|
+
var chunks = [];
|
|
2441
|
+
|
|
2442
|
+
// Signature
|
|
2443
|
+
chunks.push(new Buffer(constants.PNG_SIGNATURE));
|
|
2444
|
+
|
|
2445
|
+
// Header
|
|
2446
|
+
chunks.push(packer$1.packIHDR(metaData.width, metaData.height));
|
|
2447
|
+
|
|
2448
|
+
if (metaData.gamma) {
|
|
2449
|
+
chunks.push(packer$1.packGAMA(metaData.gamma));
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
var filteredData = packer$1.filterData(metaData.data, metaData.width, metaData.height);
|
|
2453
|
+
|
|
2454
|
+
// compress it
|
|
2455
|
+
var compressedData = zlib__default['default'].deflateSync(filteredData, packer$1.getDeflateOptions());
|
|
2456
|
+
filteredData = null;
|
|
2457
|
+
|
|
2458
|
+
if (!compressedData || !compressedData.length) {
|
|
2459
|
+
throw new Error('bad png - invalid compressed data response');
|
|
2460
|
+
}
|
|
2461
|
+
chunks.push(packer$1.packIDAT(compressedData));
|
|
2462
|
+
|
|
2463
|
+
// End
|
|
2464
|
+
chunks.push(packer$1.packIEND());
|
|
2465
|
+
|
|
2466
|
+
return Buffer.concat(chunks);
|
|
2467
|
+
};
|
|
2468
|
+
|
|
2469
|
+
var read = function(buffer, options) {
|
|
2470
|
+
|
|
2471
|
+
return parserSync(buffer, options || {});
|
|
2472
|
+
};
|
|
2473
|
+
|
|
2474
|
+
var write = function(png, options) {
|
|
2475
|
+
|
|
2476
|
+
return packerSync(png, options);
|
|
2477
|
+
};
|
|
2478
|
+
|
|
2479
|
+
var pngSync = {
|
|
2480
|
+
read: read,
|
|
2481
|
+
write: write
|
|
2482
|
+
};
|
|
2483
|
+
|
|
2484
|
+
var png = createCommonjsModule(function (module, exports) {
|
|
2485
|
+
|
|
2486
|
+
|
|
2487
|
+
|
|
2488
|
+
|
|
2489
|
+
|
|
2490
|
+
|
|
2491
|
+
|
|
2492
|
+
|
|
2493
|
+
var PNG = exports.PNG = function(options) {
|
|
2494
|
+
Stream__default['default'].call(this);
|
|
2495
|
+
|
|
2496
|
+
options = options || {}; // eslint-disable-line no-param-reassign
|
|
2497
|
+
|
|
2498
|
+
// coerce pixel dimensions to integers (also coerces undefined -> 0):
|
|
2499
|
+
this.width = options.width | 0;
|
|
2500
|
+
this.height = options.height | 0;
|
|
2501
|
+
|
|
2502
|
+
this.data = this.width > 0 && this.height > 0 ?
|
|
2503
|
+
new Buffer(4 * this.width * this.height) : null;
|
|
2504
|
+
|
|
2505
|
+
if (options.fill && this.data) {
|
|
2506
|
+
this.data.fill(0);
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
this.gamma = 0;
|
|
2510
|
+
this.readable = this.writable = true;
|
|
2511
|
+
|
|
2512
|
+
this._parser = new parserAsync(options);
|
|
2513
|
+
|
|
2514
|
+
this._parser.on('error', this.emit.bind(this, 'error'));
|
|
2515
|
+
this._parser.on('close', this._handleClose.bind(this));
|
|
2516
|
+
this._parser.on('metadata', this._metadata.bind(this));
|
|
2517
|
+
this._parser.on('gamma', this._gamma.bind(this));
|
|
2518
|
+
this._parser.on('parsed', function(data) {
|
|
2519
|
+
this.data = data;
|
|
2520
|
+
this.emit('parsed', data);
|
|
2521
|
+
}.bind(this));
|
|
2522
|
+
|
|
2523
|
+
this._packer = new packerAsync(options);
|
|
2524
|
+
this._packer.on('data', this.emit.bind(this, 'data'));
|
|
2525
|
+
this._packer.on('end', this.emit.bind(this, 'end'));
|
|
2526
|
+
this._parser.on('close', this._handleClose.bind(this));
|
|
2527
|
+
this._packer.on('error', this.emit.bind(this, 'error'));
|
|
2528
|
+
|
|
2529
|
+
};
|
|
2530
|
+
util__default['default'].inherits(PNG, Stream__default['default']);
|
|
2531
|
+
|
|
2532
|
+
PNG.sync = pngSync;
|
|
2533
|
+
|
|
2534
|
+
PNG.prototype.pack = function() {
|
|
2535
|
+
|
|
2536
|
+
if (!this.data || !this.data.length) {
|
|
2537
|
+
this.emit('error', 'No data provided');
|
|
2538
|
+
return this;
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
process.nextTick(function() {
|
|
2542
|
+
this._packer.pack(this.data, this.width, this.height, this.gamma);
|
|
2543
|
+
}.bind(this));
|
|
2544
|
+
|
|
2545
|
+
return this;
|
|
2546
|
+
};
|
|
2547
|
+
|
|
2548
|
+
|
|
2549
|
+
PNG.prototype.parse = function(data, callback) {
|
|
2550
|
+
|
|
2551
|
+
if (callback) {
|
|
2552
|
+
var onParsed, onError;
|
|
2553
|
+
|
|
2554
|
+
onParsed = function(parsedData) {
|
|
2555
|
+
this.removeListener('error', onError);
|
|
2556
|
+
|
|
2557
|
+
this.data = parsedData;
|
|
2558
|
+
callback(null, this);
|
|
2559
|
+
}.bind(this);
|
|
2560
|
+
|
|
2561
|
+
onError = function(err) {
|
|
2562
|
+
this.removeListener('parsed', onParsed);
|
|
2563
|
+
|
|
2564
|
+
callback(err, null);
|
|
2565
|
+
}.bind(this);
|
|
2566
|
+
|
|
2567
|
+
this.once('parsed', onParsed);
|
|
2568
|
+
this.once('error', onError);
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
this.end(data);
|
|
2572
|
+
return this;
|
|
2573
|
+
};
|
|
2574
|
+
|
|
2575
|
+
PNG.prototype.write = function(data) {
|
|
2576
|
+
this._parser.write(data);
|
|
2577
|
+
return true;
|
|
2578
|
+
};
|
|
2579
|
+
|
|
2580
|
+
PNG.prototype.end = function(data) {
|
|
2581
|
+
this._parser.end(data);
|
|
2582
|
+
};
|
|
2583
|
+
|
|
2584
|
+
PNG.prototype._metadata = function(metadata) {
|
|
2585
|
+
this.width = metadata.width;
|
|
2586
|
+
this.height = metadata.height;
|
|
2587
|
+
|
|
2588
|
+
this.emit('metadata', metadata);
|
|
2589
|
+
};
|
|
2590
|
+
|
|
2591
|
+
PNG.prototype._gamma = function(gamma) {
|
|
2592
|
+
this.gamma = gamma;
|
|
2593
|
+
};
|
|
2594
|
+
|
|
2595
|
+
PNG.prototype._handleClose = function() {
|
|
2596
|
+
if (!this._parser.writable && !this._packer.readable) {
|
|
2597
|
+
this.emit('close');
|
|
2598
|
+
}
|
|
2599
|
+
};
|
|
2600
|
+
|
|
2601
|
+
|
|
2602
|
+
PNG.bitblt = function(src, dst, srcX, srcY, width, height, deltaX, deltaY) { // eslint-disable-line max-params
|
|
2603
|
+
// coerce pixel dimensions to integers (also coerces undefined -> 0):
|
|
2604
|
+
/* eslint-disable no-param-reassign */
|
|
2605
|
+
srcX |= 0;
|
|
2606
|
+
srcY |= 0;
|
|
2607
|
+
width |= 0;
|
|
2608
|
+
height |= 0;
|
|
2609
|
+
deltaX |= 0;
|
|
2610
|
+
deltaY |= 0;
|
|
2611
|
+
/* eslint-enable no-param-reassign */
|
|
2612
|
+
|
|
2613
|
+
if (srcX > src.width || srcY > src.height || srcX + width > src.width || srcY + height > src.height) {
|
|
2614
|
+
throw new Error('bitblt reading outside image');
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2617
|
+
if (deltaX > dst.width || deltaY > dst.height || deltaX + width > dst.width || deltaY + height > dst.height) {
|
|
2618
|
+
throw new Error('bitblt writing outside image');
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
for (var y = 0; y < height; y++) {
|
|
2622
|
+
src.data.copy(dst.data,
|
|
2623
|
+
((deltaY + y) * dst.width + deltaX) << 2,
|
|
2624
|
+
((srcY + y) * src.width + srcX) << 2,
|
|
2625
|
+
((srcY + y) * src.width + srcX + width) << 2
|
|
2626
|
+
);
|
|
2627
|
+
}
|
|
2628
|
+
};
|
|
2629
|
+
|
|
2630
|
+
|
|
2631
|
+
PNG.prototype.bitblt = function(dst, srcX, srcY, width, height, deltaX, deltaY) { // eslint-disable-line max-params
|
|
2632
|
+
|
|
2633
|
+
PNG.bitblt(this, dst, srcX, srcY, width, height, deltaX, deltaY);
|
|
2634
|
+
return this;
|
|
2635
|
+
};
|
|
2636
|
+
|
|
2637
|
+
PNG.adjustGamma = function(src) {
|
|
2638
|
+
if (src.gamma) {
|
|
2639
|
+
for (var y = 0; y < src.height; y++) {
|
|
2640
|
+
for (var x = 0; x < src.width; x++) {
|
|
2641
|
+
var idx = (src.width * y + x) << 2;
|
|
2642
|
+
|
|
2643
|
+
for (var i = 0; i < 3; i++) {
|
|
2644
|
+
var sample = src.data[idx + i] / 255;
|
|
2645
|
+
sample = Math.pow(sample, 1 / 2.2 / src.gamma);
|
|
2646
|
+
src.data[idx + i] = Math.round(sample * 255);
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
src.gamma = 0;
|
|
2651
|
+
}
|
|
2652
|
+
};
|
|
2653
|
+
|
|
2654
|
+
PNG.prototype.adjustGamma = function() {
|
|
2655
|
+
PNG.adjustGamma(this);
|
|
2656
|
+
};
|
|
2657
|
+
});
|
|
2658
|
+
|
|
2659
|
+
function getMismatchedPixels(pixelMatchInput) {
|
|
2660
|
+
const imgA = fs__default['default'].createReadStream(pixelMatchInput.imageAPath).pipe(new png.PNG()).on('parsed', doneReading);
|
|
2661
|
+
const imgB = fs__default['default'].createReadStream(pixelMatchInput.imageBPath).pipe(new png.PNG()).on('parsed', doneReading);
|
|
2662
|
+
let filesRead = 0;
|
|
2663
|
+
function doneReading() {
|
|
2664
|
+
if (++filesRead < 2)
|
|
2665
|
+
return;
|
|
2666
|
+
const mismatchedPixels = pixelmatch_1(imgA.data, imgB.data, null, pixelMatchInput.width, pixelMatchInput.height, {
|
|
2667
|
+
threshold: pixelMatchInput.pixelmatchThreshold,
|
|
2668
|
+
includeAA: false,
|
|
2669
|
+
});
|
|
2670
|
+
process.send(mismatchedPixels);
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
process.on('message', getMismatchedPixels);
|