Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve color operations performance #1263

Merged
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
src="https://s3.amazonaws.com/pix.iemoji.com/images/emoji/apple/ios-11/256/crayon.png">
<h1>Jimp</h1>
<p>JavaScript Image Manipulation Program</p>
<p>An image processing library for Node written entirely in JavaScript, with zero native dependencies.</p>
<p>An image processing library for Node written entirely in JavaScript, with zero native dependencies</p>
</div>

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
Expand Down
38 changes: 14 additions & 24 deletions packages/core/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@
cb = args[args.length - 1];

if (typeof cb !== "function") {
// TODO: try to solve the args after cb problem.

Check warning on line 351 in packages/core/src/index.js

View workflow job for this annotation

GitHub Actions / lint

Unexpected 'todo' comment: 'TODO: try to solve the args after cb...'
cb = args[args.length - 2];

if (typeof cb !== "function") {
Expand Down Expand Up @@ -739,10 +739,6 @@
if (typeof x !== "number" || typeof y !== "number")
return throwError.call(this, "x and y must be numbers", cb);

// round input
x = Math.round(x);
y = Math.round(y);

const idx = this.getPixelIndex(x, y);
const hex = this.bitmap.data.readUInt32BE(idx);

Expand Down Expand Up @@ -771,10 +767,6 @@
)
return throwError.call(this, "hex, x and y must be numbers", cb);

// round input
x = Math.round(x);
y = Math.round(y);

const idx = this.getPixelIndex(x, y);
this.bitmap.data.writeUInt32BE(hex, idx);

Expand All @@ -792,14 +784,12 @@
* @return {boolean} hasAlpha whether the image contains opaque pixels
*/
hasAlpha() {
for (let yIndex = 0; yIndex < this.bitmap.height; yIndex++) {
for (let xIndex = 0; xIndex < this.bitmap.width; xIndex++) {
const idx = (this.bitmap.width * yIndex + xIndex) << 2;
const alpha = this.bitmap.data[idx + 3];
const {width, height, data} = this.bitmap;
const byteLen = (width * height) << 2;

if (alpha !== 0xff) {
return true;
}
for (let idx = 3; idx < byteLen; idx += 4) {
if (data[idx] !== 0xff) {
return true;
}
}

Expand Down Expand Up @@ -879,7 +869,7 @@
* @param {function(Error, Jimp)} cb (optional) A callback for when complete
* @returns {number} an single integer colour value
*/
Jimp.rgbaToInt = function (r, g, b, a, cb) {

Check warning on line 872 in packages/core/src/index.js

View workflow job for this annotation

GitHub Actions / lint

Function has too many parameters (5). Maximum allowed is 4
if (
typeof r !== "number" ||
typeof g !== "number" ||
Expand All @@ -905,16 +895,16 @@
return throwError.call(this, "a must be between 0 and 255", cb);
}

r = Math.round(r);
b = Math.round(b);
g = Math.round(g);
a = Math.round(a);
let i = (r & 0xff);
i <<= 8;
i |= (g & 0xff)
i <<= 8;
i |= (b & 0xff)
i <<= 8;
i |= (a & 0xff);

const i =
r * Math.pow(256, 3) +
g * Math.pow(256, 2) +
b * Math.pow(256, 1) +
a * Math.pow(256, 0);
// Ensure sign is correct
i >>>= 0;

if (isNodePattern(cb)) {
cb.call(this, null, i);
Expand Down Expand Up @@ -1204,7 +1194,7 @@
* @param {function(Error, Jimp)} cb (optional) a callback for when complete
* @returns {Jimp} this for chaining of methods
*/
jimpEvChange("scan", function (x, y, w, h, f, cb) {

Check warning on line 1197 in packages/core/src/index.js

View workflow job for this annotation

GitHub Actions / lint

Function has too many parameters (6). Maximum allowed is 4
if (typeof x !== "number" || typeof y !== "number") {
return throwError.call(this, "x and y must be numbers", cb);
}
Expand Down
29 changes: 12 additions & 17 deletions packages/core/src/modules/phash.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,24 +125,19 @@ ImagePHash.prototype.getHash = function (img) {

// DCT function stolen from http://stackoverflow.com/questions/4240490/problems-with-dct-and-idct-algorithm-in-java

/**
Convert a 32-bit integer color value to an RGBA object.
*/
function intToRGBA(i) {
const rgba = {};

rgba.r = Math.floor(i / Math.pow(256, 3));
rgba.g = Math.floor((i - rgba.r * Math.pow(256, 3)) / Math.pow(256, 2));
rgba.b = Math.floor(
(i - rgba.r * Math.pow(256, 3) - rgba.g * Math.pow(256, 2)) /
Math.pow(256, 1)
);
rgba.a = Math.floor(
(i -
rgba.r * Math.pow(256, 3) -
rgba.g * Math.pow(256, 2) -
rgba.b * Math.pow(256, 1)) /
Math.pow(256, 0)
);

return rgba;
const a = i & 0xff;
i >>>= 8;
const b = i & 0xff;
i >>>= 8;
const g = i & 0xff;
i >>>= 8;
const r = i & 0xff;

return {r, g, b, a};
}

const c = [];
Expand Down