Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pam-diff

Package Overview
Dependencies
Maintainers
1
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pam-diff - npm Package Compare versions

Comparing version 0.13.1 to 0.13.2

src/async.cc

220

index.js

@@ -7,3 +7,3 @@ 'use strict';

const PC = require('bindings')('addon');
const addon = require('bindings')('addon');

@@ -17,2 +17,3 @@ class PamDiff extends Transform {

* @param [options.percent=5] {Number} - Percent of pixels that exceed difference value.
* @param [options.response=percent] {String} - Accepted values: percent or bounds.
* @param [options.regions] {Array} - Array of regions.

@@ -30,2 +31,3 @@ * @param options.regions[i].name {String} - Name of region.

Transform.call(this, {objectMode: true});
this.response = PamDiff._parseOptions('response', options);//percent, bounds, blobs
this.async = PamDiff._parseOptions('async', options);// should be processed before regions

@@ -35,3 +37,3 @@ this.difference = PamDiff._parseOptions('difference', options);// global value, can be overridden per region

this.mask = PamDiff._parseOptions('mask', options);// should be processed before regions
this.blobSize = PamDiff._parseOptions('blobSize', options);// should be processed before regions
//this.blobSize = PamDiff._parseOptions('blobSize', options);// should be processed before regions
this.regions = PamDiff._parseOptions('regions', options);// can be zero regions, a single region, or multiple regions. if no regions, all pixels will be compared.

@@ -89,2 +91,44 @@ this.callback = callback;// callback function to be called when pixel difference is detected

*
* @param string {String}
* @param strings {Array}
* @return {String}
* @private
*/
static _validateString(string, strings) {
if (strings.includes(string)) {
return string;
}
return strings[0];
}
/**
*
* @param string {String}
*/
set response(string) {
this._response = PamDiff._validateString(string, ['percent', 'bounds', 'blobs']);
this._processRegions();
this._configurePixelDiffEngine();
}
/**
*
* @return {String}
*/
get response() {
return this._response || null;
}
/**
*
* @param string {String}
* @return {PamDiff}
*/
setResponse(string) {
this.response = string;
return this;
}
/**
*
* @param bool {Boolean}

@@ -225,6 +269,6 @@ */

*/
/*set blobSize(number) {
set blobSize(number) {
this._blobSize = PamDiff._validateNumber(parseInt(number), 0, 0, 100000);
this._configurePixelDiffEngine();
}*/
}

@@ -235,5 +279,5 @@ /**

*/
/*get blobSize() {
get blobSize() {
return this._blobSize || 0;
}*/
}

@@ -245,6 +289,6 @@ /**

*/
/*setBlobSize(number) {
setBlobSize(number) {
this.blobSize = number;
return this;
}*/
}

@@ -288,2 +332,3 @@ /**

resetCache() {
delete this._engine;
delete this._oldPix;

@@ -297,3 +342,2 @@ delete this._newPix;

delete this._maskObj;
delete this._pixelDiffEngine;
this._parseChunk = this._parseFirstChunk;

@@ -370,97 +414,41 @@ return this;

const wxh = this._width * this._height;
let engine = this._tupltype;
let parser = '';
engine += `_${this._width}_x_${this._height}`;
const config = {width: this._width, height: this._height, depth: this._depth, response: this._response, async: this._async};
if (this._regionObj) {
engine += '_regions';
config.target = 'regions';
config.minDiff = this._regionObj.minDiff;
config.regions = this._regionObj.regions;
} else if (this._maskObj) {
engine += '_mask';
config.target = 'mask';
config.difference = this._difference;
config.percent = this._percent;
config.bitsetCount = this._maskObj.count;
config.bitset = this._maskObj.bitset;
} else {
engine += '_all';
config.target = 'all';
config.difference = this._difference;
config.percent = this._percent;
}
if (this._blobSize) {
engine += '_blob';
}
engine += `_${this._response}`;
if (this._async) {
engine += '_async';
parser += 'async';
} else {
engine += '_sync';
parser += 'sync';
}
engine += this._async ? '_async' : '_sync';
this._engine = addon(config);
if (process.env.NODE_ENV === 'development') {
parser += '_dev';
this._parseChunk = this._parsePixelsDebug;
this._debugEngine = engine;
this._debugCount = 0;
} else {
this._parseChunk = this._parsePixels;
}
switch (engine) {
case 'grayscale_all_sync' :
this._pixelDiffEngine = PC.grayDiffAllSync.bind(this, wxh, this._difference, this._percent);
break;
case 'grayscale_mask_sync' :
this._pixelDiffEngine = PC.grayDiffMaskSync.bind(this, wxh, this._difference, this._percent, this._maskObj.count, this._maskObj.bitset);
break;
case 'grayscale_regions_sync' :
this._pixelDiffEngine = PC.grayDiffRegionsSync.bind(this, wxh, this._regionObj.minDiff, this._regionObj.length, this._regionObj.regions);
break;
case 'grayscale_all_async' :
this._pixelDiffEngine = PC.grayDiffAllAsync.bind(this, wxh, this._difference, this._percent);
break;
case 'grayscale_mask_async' :
this._pixelDiffEngine = PC.grayDiffMaskAsync.bind(this, wxh, this._difference, this._percent, this._maskObj.count, this._maskObj.bitset);
break;
case 'grayscale_regions_async' :
this._pixelDiffEngine = PC.grayDiffRegionsAsync.bind(this, wxh, this._regionObj.minDiff, this._regionObj.length, this._regionObj.regions);
break;
case 'rgb_all_sync' :
case 'rgb_alpha_all_sync' :
this._pixelDiffEngine = PC.rgbDiffAllSync.bind(this, wxh, this._depth, this._difference, this._percent);
break;
case 'rgb_mask_sync' :
case 'rgb_alpha_mask_sync' :
this._pixelDiffEngine = PC.rgbDiffMaskSync.bind(this, wxh, this._depth, this._difference, this._percent, this._maskObj.count, this._maskObj.bitset);
break;
case 'rgb_regions_sync' :
case 'rgb_alpha_regions_sync' :
this._pixelDiffEngine = PC.rgbDiffRegionsSync.bind(this, wxh, this._depth, this._regionObj.minDiff, this._regionObj.length, this._regionObj.regions);
break;
case 'rgb_all_async' :
case 'rgb_alpha_all_async' :
this._pixelDiffEngine = PC.rgbDiffAllAsync.bind(this, wxh, this._depth, this._difference, this._percent);
break;
case 'rgb_mask_async' :
case 'rgb_alpha_mask_async' :
this._pixelDiffEngine = PC.rgbDiffMaskAsync.bind(this, wxh, this._depth, this._difference, this._percent, this._maskObj.count, this._maskObj.bitset);
break;
case 'rgb_regions_async' :
case 'rgb_alpha_regions_async' :
this._pixelDiffEngine = PC.rgbDiffRegionsAsync.bind(this, wxh, this._depth, this._regionObj.minDiff, this._regionObj.length, this._regionObj.regions);
break;
default:
throw new Error(`Did not find a matching engine for ${engine}`);
}
switch (parser) {
case 'sync':
this._parseChunk = this._parsePixelsSync;
break;
case 'sync_dev':
this._parseChunk = this._parsePixelsSyncDebug;
break;
case 'async':
this._parseChunk = this._parsePixelsAsync;
break;
case 'async_dev':
this._parseChunk = this._parsePixelsAsyncDebug;
break;
default:
throw new Error(`Did not find a matching parser for ${parser}`);
}
}

@@ -473,49 +461,6 @@

*/
_parsePixelsSync(chunk) {
_parsePixels(chunk) {
this._newPix = chunk.pixels;
const results = this._pixelDiffEngine(this._oldPix, this._newPix);
if (results.length) {
const data = {trigger: results, pam: chunk.pam};
if (this._callback) {
this._callback(data);
}
if (this._readableState.pipesCount > 0) {
this.push(data);
}
if (this.listenerCount('diff') > 0) {
this.emit('diff', data);
}
}
this._oldPix = this._newPix;
}
/**
*
* @param chunk
* @private
*/
_parsePixelsSyncDebug(chunk) {
const debugCount = this._debugCount++;
console.time(`${this._debugEngine}-${debugCount}`);
this._newPix = chunk.pixels;
const results = this._pixelDiffEngine(this._oldPix, this._newPix);
if (results.length) {
const data = {trigger: results, pam: chunk.pam};
if (this._callback) {
this._callback(data);
}
if (this._readableState.pipesCount > 0) {
this.push(data);
}
if (this.listenerCount('diff') > 0) {
this.emit('diff', data);
}
}
this._oldPix = this._newPix;
console.timeEnd(`${this._debugEngine}-${debugCount}`);
}
_parsePixelsAsync(chunk) {
this._newPix = chunk.pixels;
this._pixelDiffEngine(this._oldPix, this._newPix, (err, results) => {
this._engine.compare(this._oldPix, this._newPix, (err, results) => {
//this._pixelDiffEngine(this._oldPix, this._newPix, (err, results) => {
if (results.length) {

@@ -537,7 +482,13 @@ const data = {trigger: results, pam: chunk.pam};

_parsePixelsAsyncDebug(chunk) {
/**
*
* @param chunk
* @private
*/
_parsePixelsDebug(chunk) {
const debugCount = this._debugCount++;
console.time(`${this._debugEngine}-${debugCount}`);
this._newPix = chunk.pixels;
this._pixelDiffEngine(this._oldPix, this._newPix, (err, results) => {
this._engine.compare(this._oldPix, this._newPix, (err, results) => {
//this._pixelDiffEngine(this._oldPix, this._newPix, (err, results) => {
if (results.length) {

@@ -560,3 +511,2 @@ const data = {trigger: results, pam: chunk.pam};

/**

@@ -563,0 +513,0 @@ *

{
"name": "pam-diff",
"version": "0.13.1",
"version": "0.13.2",
"description": "Measure differences between pixel arrays extracted from pam images",

@@ -8,5 +8,5 @@ "main": "index.js",

"install": "node-gyp rebuild",
"pretest": "npm install",
"__pretest": "npm install",
"test": "npm run gray && npm run rgb && npm run rgba",
"preversion": "npm test",
"preversion": "npm install && npm test",
"postversion": "npm run doc && npm run doc:commit",

@@ -18,6 +18,53 @@ "examples": "node examples/example && node examples/example2 && node examples/example3 && node examples/example4 && node examples/example5",

"doc:commit": "git commit -m \"update docs\" -- docs",
"__gray": "node tests/test_gray && node tests/test_gray2 && node tests/test_gray3 && node tests/test_gray4 && node tests/test_gray5 && node tests/test_gray6",
"gray": "node tests/test_gray && node tests/test_gray2 && node tests/test_gray3 && node tests/test_gray4",
"rgb": "node tests/test_rgb && node tests/test_rgb2 && node tests/test_rgb3 && node tests/test_rgb4",
"rgba": "node tests/test_rgba && node tests/test_rgba2 && node tests/test_rgba3 && node tests/test_rgba4",
"gray": "npm run gray:1 && npm run gray:2 && npm run gray:3 && npm run gray:4 && npm run gray:5 && npm run gray:6 && npm run gray:7 && npm run gray:8 && npm run gray:9 && npm run gray:10 && npm run gray:11 && npm run gray:12 && npm run gray:13 && npm run gray:14 && npm run gray:15 && npm run gray:16",
"gray:1": "node tests/test_gray --async false --response percent",
"gray:2": "node tests/test_gray2 --async false --response percent",
"gray:3": "node tests/test_gray3 --async false --response percent",
"gray:4": "node tests/test_gray4 --async false --response percent",
"gray:5": "node tests/test_gray --async false --response bounds",
"gray:6": "node tests/test_gray2 --async false --response bounds",
"gray:7": "node tests/test_gray3 --async false --response bounds",
"gray:8": "node tests/test_gray4 --async false --response bounds",
"gray:9": "node tests/test_gray --async true --response percent",
"gray:10": "node tests/test_gray2 --async true --response percent",
"gray:11": "node tests/test_gray3 --async true --response percent",
"gray:12": "node tests/test_gray4 --async true --response percent",
"gray:13": "node tests/test_gray --async true --response bounds",
"gray:14": "node tests/test_gray2 --async true --response bounds",
"gray:15": "node tests/test_gray3 --async true --response bounds",
"gray:16": "node tests/test_gray4 --async true --response bounds",
"rgb": "npm run rgb:1 && npm run rgb:2 && npm run rgb:3 && npm run rgb:4 && npm run rgb:5 && npm run rgb:6 && npm run rgb:7 && npm run rgb:8 && npm run rgb:9 && npm run rgb:10 && npm run rgb:11 && npm run rgb:12 && npm run rgb:13 && npm run rgb:14 && npm run rgb:15 && npm run rgb:16",
"rgb:1": "node tests/test_rgb --async false --response percent",
"rgb:2": "node tests/test_rgb2 --async false --response percent",
"rgb:3": "node tests/test_rgb3 --async false --response percent",
"rgb:4": "node tests/test_rgb4 --async false --response percent",
"rgb:5": "node tests/test_rgb --async false --response bounds",
"rgb:6": "node tests/test_rgb2 --async false --response bounds",
"rgb:7": "node tests/test_rgb3 --async false --response bounds",
"rgb:8": "node tests/test_rgb4 --async false --response bounds",
"rgb:9": "node tests/test_rgb --async true --response percent",
"rgb:10": "node tests/test_rgb2 --async true --response percent",
"rgb:11": "node tests/test_rgb3 --async true --response percent",
"rgb:12": "node tests/test_rgb4 --async true --response percent",
"rgb:13": "node tests/test_rgb --async true --response bounds",
"rgb:14": "node tests/test_rgb2 --async true --response bounds",
"rgb:15": "node tests/test_rgb3 --async true --response bounds",
"rgb:16": "node tests/test_rgb4 --async true --response bounds",
"rgba": "npm run rgba:1 && npm run rgba:2 && npm run rgba:3 && npm run rgba:4 && npm run rgba:5 && npm run rgba:6 && npm run rgba:7 && npm run rgba:8 && npm run rgba:9 && npm run rgba:10 && npm run rgba:11 && npm run rgba:12 && npm run rgba:13 && npm run rgba:14 && npm run rgba:15 && npm run rgba:16",
"rgba:1": "node tests/test_rgba --async false --response percent",
"rgba:2": "node tests/test_rgba2 --async false --response percent",
"rgba:3": "node tests/test_rgba3 --async false --response percent",
"rgba:4": "node tests/test_rgba4 --async false --response percent",
"rgba:5": "node tests/test_rgba --async false --response bounds",
"rgba:6": "node tests/test_rgba2 --async false --response bounds",
"rgba:7": "node tests/test_rgba3 --async false --response bounds",
"rgba:8": "node tests/test_rgba4 --async false --response bounds",
"rgba:9": "node tests/test_rgba --async true --response percent",
"rgba:10": "node tests/test_rgba2 --async true --response percent",
"rgba:11": "node tests/test_rgba3 --async true --response percent",
"rgba:12": "node tests/test_rgba4 --async true --response percent",
"rgba:13": "node tests/test_rgba --async true --response bounds",
"rgba:14": "node tests/test_rgba2 --async true --response bounds",
"rgba:15": "node tests/test_rgba3 --async true --response bounds",
"rgba:16": "node tests/test_rgba4 --async true --response bounds",
"pub": "npm publish -tag latest",

@@ -56,5 +103,9 @@ "__pub": "npm publish",

"jsdoc": "^3.5.5",
"minimist": "^1.2.0",
"pipe2pam": "^0.6.2"
},
"private": false
"private": false,
"files": [
"src"
]
}

@@ -8,4 +8,5 @@ # pam-diff

```
#### *Important Note*: The js-only version will no longer receive any updates. All future work will be dedicated to the n-api version because it is much more efficient.
#### *New Feature*: Starting with version 0.13.0, the option to use worker threads can be enabled by passing `{async: true}` to the pam-diff constructor.
#### *Important Note:* The js-only version will no longer receive any updates. All future work will be dedicated to the n-api version because it is much more efficient.
#### *New Feature:* Starting with version 0.13.0, the option to use worker threads can be enabled by passing `{async: true}` to the pam-diff constructor.
#### *New Feature:* Starting with version 0.13.2, the option to get x y bounding box coordinates can be set by passing `{response: "bounds"}` to the pam-diff constructor.
### Usage Options:

@@ -16,86 +17,95 @@ ##### When comparing 2 equally sized buffers of grayscale, rgb, or rgba pixels, there are several options:

- To use this option, set the configuration object without creating any regions.
- ```javascript
const pamDiff = new PamDiff({difference: 5, percent: 5});
```
```javascript
const pamDiff = new PamDiff({difference: 5, percent: 5});
```
2. regions
- Specific regions of pixels will be targeted when checking for differences and the rest will be ignored.
- To use this option, create a regions array and pass it to the constructor.
- ```javascript
const region1 = {name: 'region1', difference: 12, percent: 22, polygon: [{x: 0, y: 0}, {x: 0, y: 225}, {x: 100, y: 225}, {x: 100, y: 0}]};
const region2 = {name: 'region2', difference: 14, percent: 10, polygon: [{x: 100, y: 0}, {x: 100, y: 225}, {x: 200, y: 225}, {x: 200, y: 0}]};
const regions = [region1, region2];
const pamDiff = new PamDiff({regions : regions});
```
```javascript
const region1 = {name: 'region1', difference: 12, percent: 22, polygon: [{x: 0, y: 0}, {x: 0, y: 225}, {x: 100, y: 225}, {x: 100, y: 0}]};
const region2 = {name: 'region2', difference: 14, percent: 10, polygon: [{x: 100, y: 0}, {x: 100, y: 225}, {x: 200, y: 225}, {x: 200, y: 0}]};
const regions = [region1, region2];
const pamDiff = new PamDiff({regions : regions});
```
3. mask
- Specific regions of pixels will be ignored when checking for differences.
- To use this option, create a regions array and set the mask option to true.
- ```javascript
const region1 = {name: 'region1', polygon: [{x: 0, y: 0}, {x: 0, y: 225}, {x: 100, y: 225}, {x: 100, y: 0}]};
const region2 = {name: 'region2', polygon: [{x: 100, y: 0}, {x: 100, y: 225}, {x: 200, y: 225}, {x: 200, y: 0}]};
const regions = [region1, region2];
const pamDiff = new PamDiff({difference: 12, percent: 10, mask: true, regions : regions});
```
```javascript
const region1 = {name: 'region1', polygon: [{x: 0, y: 0}, {x: 0, y: 225}, {x: 100, y: 225}, {x: 100, y: 0}]};
const region2 = {name: 'region2', polygon: [{x: 100, y: 0}, {x: 100, y: 225}, {x: 200, y: 225}, {x: 200, y: 0}]};
const regions = [region1, region2];
const pamDiff = new PamDiff({difference: 12, percent: 10, mask: true, regions : regions});
```
##### Getting results back from the pixel difference detection:
1. event
- A *diff* event will be emitted with a data object passed as the only argument.
- ```javascript
pamDiff.on('diff', data => {
console.log(data);
});
```
```javascript
pamDiff.on('diff', data => {
console.log(data);
});
```
2. callback
- A *callback* function will be called with a data object passed as the only argument.
- The callback can be passed as the 2nd argument to the constructor or it can be added later.
- ```javascript
//callback function
function myCallback(data) {
console.log(data);
}
```javascript
/* callback function */
function myCallback(data) {
console.log(data);
}
//via the constructor
const pamDiff = new pamDiff({difference: 10, percent: 20}, myCallback);
/* via the constructor */
const pamDiff = new pamDiff({difference: 10, percent: 20}, myCallback);
//via the setter
pamDiff.callback = myCallback;
/* via the setter */
pamDiff.callback = myCallback;
//via the chain-able setter
pamDiff.setCallback(myCallback).setDifference(10).setPercent(20);
/* via the chain-able setter */
pamDiff.setCallback(myCallback).setDifference(10).setPercent(20);
//remove the callback
pamDiff.callback = null;
```
/* remove the callback */
pamDiff.callback = null;
```
##### Expected results:
1. When targeting all pixels:
- ```
{
trigger: [
{name: 'all', percent: 13}
],
pam: <Buffer>
}
```
```
{
trigger: [
{name: 'all', percent: 13}
],
pam: <Buffer>
}
```
2. When targeting regions of pixels:
- ```
{
trigger: [
{name: 'region1', percent: 13},
{name: 'region2', percent: 22}
],
pam: <Buffer>
}
```
```
{
trigger: [
{name: 'region1', percent: 13},
{name: 'region2', percent: 22}
],
pam: <Buffer>
}
```
3. When targeting all pixels ignored by mask:
- ```
{
trigger: [
{name: 'mask', percent: 13}
],
pam: <Buffer>
}
```
```
{
trigger: [
{name: 'mask', percent: 13}
],
pam: <Buffer>
}
```
4. When targeting all pixels and setting {response: "bounds"}:
```
{
trigger: [
{name: 'all', percent: 13, minX: 42, maxX: 399, minY: 113, maxY: 198}
],
pam: <Buffer>
}
```
### Other Resources:
View the [docs](https://kevingodell.github.io/pam-diff/PamDiff.html), [tests](https://github.com/kevinGodell/pam-diff/tree/master/tests), or [examples](https://github.com/kevinGodell/pam-diff/tree/master/examples) for more implementations.
### Future Plans:
- Add node-pre-gyp as an option for installing pre-built binaries for those who are unable to use node-gyp. (Not a priority at this point)
- Include option to return coordinates for bounding box of changed pixels.
- Introduce blob filtering to group changed pixels with their neighbors.
- [ ] Add node-pre-gyp as an option for installing pre-built binaries for those who are unable to use node-gyp. (Not a priority at this point)
- [x] Include option to return coordinates for bounding box of changed pixels.
- [ ] Introduce blob filtering to group changed pixels with their neighbors.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc