Skip to content

Commit bf7001f

Browse files
Handle “undefined” as passed option values (#146)
Allow the consumers to pass “undefined” as options values instead of misbehaving. Today if the consumer passes “undefined”, we ignore the default options and allow the “undefined” value to fall through to the rest of the program, resulting in undefined behavior. For an example, the maxDelta becomes NaN if threshold: undefined is provided. After this change we ensure that “undefined” as options values is converted into a default value. It is customary in JavaScript, especially in options objects, to treat a missing key and a key with value of undefined the same way. In particular, it is a distinction that is easily introduced when the customer receives a value from somewhere else and wants to continue to support default values.
1 parent cce03e1 commit bf7001f

File tree

3 files changed

+19
-21
lines changed

3 files changed

+19
-21
lines changed

index.js

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11

2-
const defaultOptions = {
3-
threshold: 0.1, // matching threshold (0 to 1); smaller is more sensitive
4-
includeAA: false, // whether to skip anti-aliasing detection
5-
alpha: 0.1, // opacity of original image in diff output
6-
aaColor: [255, 255, 0], // color of anti-aliased pixels in diff output
7-
diffColor: [255, 0, 0], // color of different pixels in diff output
8-
diffColorAlt: null, // whether to detect dark on light differences between img1 and img2 and set an alternative color to differentiate between the two
9-
diffMask: false // draw the diff over a transparent background (a mask)
10-
};
11-
122
export default function pixelmatch(img1, img2, output, width, height, options) {
3+
const {
4+
threshold = 0.1, // matching threshold (0 to 1); smaller is more sensitive
5+
includeAA = false, // whether to skip anti-aliasing detection
6+
alpha = 0.1, // opacity of original image in diff output
7+
aaColor = [255, 255, 0], // color of anti-aliased pixels in diff output
8+
diffColor = [255, 0, 0], // color of different pixels in diff output
9+
diffColorAlt = null, // whether to detect dark on light differences between img1 and img2 and set an alternative color to differentiate between the two
10+
diffMask = false // draw the diff over a transparent background (a mask)
11+
} = options;
1312

1413
if (!isPixelData(img1) || !isPixelData(img2) || (output && !isPixelData(output)))
1514
throw new Error('Image data: Uint8Array, Uint8ClampedArray or Buffer expected.');
@@ -19,8 +18,6 @@ export default function pixelmatch(img1, img2, output, width, height, options) {
1918

2019
if (img1.length !== width * height * 4) throw new Error('Image data size does not match width/height.');
2120

22-
options = Object.assign({}, defaultOptions, options);
23-
2421
// check if images are identical
2522
const len = width * height;
2623
const a32 = new Uint32Array(img1.buffer, img1.byteOffset, len);
@@ -31,18 +28,18 @@ export default function pixelmatch(img1, img2, output, width, height, options) {
3128
if (a32[i] !== b32[i]) { identical = false; break; }
3229
}
3330
if (identical) { // fast path if identical
34-
if (output && !options.diffMask) {
35-
for (let i = 0; i < len; i++) drawGrayPixel(img1, 4 * i, options.alpha, output);
31+
if (output && !diffMask) {
32+
for (let i = 0; i < len; i++) drawGrayPixel(img1, 4 * i, alpha, output);
3633
}
3734
return 0;
3835
}
3936

4037
// maximum acceptable square distance between two colors;
4138
// 35215 is the maximum possible value for the YIQ difference metric
42-
const maxDelta = 35215 * options.threshold * options.threshold;
43-
const [aaR, aaG, aaB] = options.aaColor;
44-
const [diffR, diffG, diffB] = options.diffColor;
45-
const [altR, altG, altB] = options.diffColorAlt || options.diffColor;
39+
const maxDelta = 35215 * threshold * threshold;
40+
const [aaR, aaG, aaB] = aaColor;
41+
const [diffR, diffG, diffB] = diffColor;
42+
const [altR, altG, altB] = diffColorAlt || diffColor;
4643
let diff = 0;
4744

4845
// compare each pixel of one image against the other one
@@ -57,11 +54,11 @@ export default function pixelmatch(img1, img2, output, width, height, options) {
5754
// the color difference is above the threshold
5855
if (Math.abs(delta) > maxDelta) {
5956
// check it's a real rendering difference or just anti-aliasing
60-
if (!options.includeAA && (antialiased(img1, x, y, width, height, img2) ||
57+
if (!includeAA && (antialiased(img1, x, y, width, height, img2) ||
6158
antialiased(img2, x, y, width, height, img1))) {
6259
// one of the pixels is anti-aliasing; draw as yellow and do not count as difference
6360
// note that we do not include such pixels in a mask
64-
if (output && !options.diffMask) drawPixel(output, pos, aaR, aaG, aaB);
61+
if (output && !diffMask) drawPixel(output, pos, aaR, aaG, aaB);
6562

6663
} else {
6764
// found substantial difference not caused by anti-aliasing; draw it as such
@@ -77,7 +74,7 @@ export default function pixelmatch(img1, img2, output, width, height, options) {
7774

7875
} else if (output) {
7976
// pixels are similar; draw background as grayscale image blended with white
80-
if (!options.diffMask) drawGrayPixel(img1, pos, options.alpha, output);
77+
if (!diffMask) drawGrayPixel(img1, pos, alpha, output);
8178
}
8279
}
8380
}
25 KB
Loading

test/test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import match from '../index.js';
99
const options = {threshold: 0.05};
1010

1111
diffTest('1a', '1b', '1diff', options, 143);
12+
diffTest('1a', '1b', '1diffdefaultthreshold', {threshold: undefined}, 106);
1213
diffTest('1a', '1b', '1diffmask', {threshold: 0.05, includeAA: false, diffMask: true}, 143);
1314
diffTest('1a', '1a', '1emptydiffmask', {threshold: 0, diffMask: true}, 0);
1415
diffTest('2a', '2b', '2diff', {

0 commit comments

Comments
 (0)