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

@applitools/screenshoter

Package Overview
Dependencies
Maintainers
22
Versions
173
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@applitools/screenshoter - npm Package Compare versions

Comparing version 3.0.6 to 3.0.7

docker-compose.yaml

2

.bongo/dry-run/package-lock.json

@@ -7,3 +7,3 @@ {

"version": "file:../dry-run.tgz",
"integrity": "sha512-EVXuU3UF5h7CGPUZFqhSAnO99kIHiF1nu/KFbXtpdY7F06id3JFbj6pGqjPDLg7RZlstx4XzPUWCBhUbmf/Y/Q==",
"integrity": "sha512-m+EtXKrNrh5j2eiVtOeinQXOBvb+lgHV0CM8Vvl9RKwaJNAA1ApkAhaGkZy7uowL+6FfGOrWW2zrhkcmL0BYGw==",
"requires": {

@@ -10,0 +10,0 @@ "@applitools/utils": "1.1.3",

@@ -7,2 +7,7 @@

## 3.0.7 - 2021/5/13
fixed image cropping algorithm to not copy data into a heap
optimized image rotation and image copping algorithms
## 3.0.6 - 2021/5/11

@@ -9,0 +14,0 @@

{
"name": "@applitools/screenshoter",
"version": "3.0.6",
"version": "3.0.7",
"description": "Applitools universal screenshoter for web and native applications",

@@ -51,11 +51,11 @@ "keywords": [

"test": "yarn test:it && yarn test:coverage",
"test:it": "mocha --no-timeouts './test/it/*.spec.js'",
"test:coverage": "mocha --no-timeouts './test/coverage/*.spec.js'",
"test:it": "mocha --no-timeouts './test/it/*.spec.js'",
"preversion": "bongo preversion && yarn test",
"version": "bongo version",
"postversion": "bongo postversion --skip-release-notification",
"deps": "bongo deps",
"docker:setup": "node ../sdk-shared/src/generate-docker-compose-config.js && docker-compose up -d",
"docker:teardown": "docker-compose down",
"prepublish:setup": "yarn docker:setup"
"setup": "yarn docker:setup",
"deps": "bongo deps",
"preversion": "bongo preversion",
"version": "bongo version",
"postversion": "bongo postversion --skip-release-notification"
},

@@ -62,0 +62,0 @@ "license": "SEE LICENSE IN LICENSE",

@@ -141,3 +141,3 @@ const fs = require('fs')

async function crop(image, region) {
if (utils.types.has(region, 'left')) {
if (utils.types.has(region, ['left', 'right', 'top', 'bottom'])) {
region = {

@@ -151,23 +151,29 @@ x: region.left,

// process the pixels - crop
const croppedArray = []
const yStart = Math.max(0, Math.round(region.y))
const yEnd = Math.min(image.height, Math.round(region.y + region.height))
const xStart = Math.max(0, Math.round(region.x))
const xEnd = Math.min(image.width, Math.round(region.width + region.x))
const srcX = Math.max(0, Math.round(region.x))
const srcY = Math.max(0, Math.round(region.y))
const dstWidth = Math.round(Math.min(image.width - srcX, region.width))
const dstHeight = Math.round(Math.min(image.height - srcY, region.height))
let y, x, idx, i
for (y = yStart; y < yEnd; y += 1) {
for (x = xStart; x < xEnd; x += 1) {
idx = (image.width * y + x) * 4
for (i = 0; i < 4; i += 1) {
croppedArray.push(image.data[idx + i])
}
}
if (srcX === 0 && dstWidth === image.width) {
const srcOffset = srcY * image.width * 4
const dstLength = dstWidth * dstHeight * 4
image.data = image.data.subarray(srcOffset, srcOffset + dstLength)
image.width = dstWidth
image.height = dstHeight
return image
}
image.data = Buffer.from(croppedArray)
image.width = xEnd - xStart
image.height = yEnd - yStart
const cropped = Buffer.alloc(dstWidth * dstHeight * 4)
const chunkLength = dstWidth * 4
for (let chunk = 0; chunk < dstHeight; ++chunk) {
const srcOffset = ((srcY + chunk) * image.width + srcX) * 4
cropped.set(image.data.subarray(srcOffset, srcOffset + chunkLength), chunk * chunkLength)
}
image.data = cropped
image.width = dstWidth
image.height = dstHeight
return image

@@ -177,28 +183,42 @@ }

async function rotate(image, degrees) {
let i = Math.round(degrees / 90) % 4
while (i < 0) {
i += 4
degrees = (360 + degrees) % 360
const dstImage = {
data: Buffer.alloc(image.data.length),
}
while (i > 0) {
const dstBuffer = Buffer.alloc(image.data.length)
let dstOffset = 0
for (let x = 0; x < image.width; x += 1) {
for (let y = image.height - 1; y >= 0; y -= 1) {
const srcOffset = (image.width * y + x) * 4
const data = image.data.readUInt32BE(srcOffset)
dstBuffer.writeUInt32BE(data, dstOffset)
dstOffset += 4
if (degrees === 90) {
dstImage.width = image.height
dstImage.height = image.width
for (let srcY = 0, dstX = image.height - 1; srcY < image.height; ++srcY, --dstX) {
for (let srcX = 0, dstY = 0; srcX < image.width; ++srcX, ++dstY) {
const pixel = image.data.readUInt32BE((srcY * image.width + srcX) * 4)
dstImage.data.writeUInt32BE(pixel, (dstY * dstImage.width + dstX) * 4)
}
}
} else if (degrees === 180) {
dstImage.width = image.width
dstImage.height = image.height
for (let srcY = 0, dstY = image.height - 1; srcY < image.height; ++srcY, --dstY) {
for (let srcX = 0, dstX = image.width - 1; srcX < image.width; ++srcX, --dstX) {
const pixel = image.data.readUInt32BE((srcY * image.width + srcX) * 4)
dstImage.data.writeUInt32BE(pixel, (dstY * dstImage.width + dstX) * 4)
}
}
} else if (degrees === 270) {
dstImage.width = image.height
dstImage.height = image.width
for (let srcY = 0, dstX = 0; srcY < image.height; ++srcY, ++dstX) {
for (let srcX = 0, dstY = image.width - 1; srcX < image.width; ++srcX, --dstY) {
const pixel = image.data.readUInt32BE((srcY * image.width + srcX) * 4)
dstImage.data.writeUInt32BE(pixel, (srcX * dstImage.width + dstY) * 4)
}
}
} else {
return image
}
image.data = Buffer.from(dstBuffer)
const tmp = image.width
image.data = dstImage.data
image.width = dstImage.width
image.height = dstImage.height
image.width = image.height
image.height = tmp
i -= 1
}
return image

@@ -208,26 +228,19 @@ }

async function copy(dstImage, srcImage, offset) {
const offsetX = Math.round(offset.x)
const offsetY = Math.round(offset.y)
const dstX = Math.round(offset.x)
const dstY = Math.round(offset.y)
const srcWidth = Math.min(srcImage.width, dstImage.width - dstX)
const srcHeight = Math.min(srcImage.height, dstImage.height - dstY)
// Fix the problem when src image was out of dst image and pixels was copied to wrong position in dst image.
const maxHeight =
offsetY + srcImage.height <= dstImage.height ? srcImage.height : dstImage.height - offsetY
const maxWidth =
offsetX + srcImage.width <= dstImage.width ? srcImage.width : dstImage.width - offsetX
if (dstX === 0 && srcWidth === dstImage.width && srcWidth === srcImage.width) {
const dstOffset = dstY * dstImage.width * 4
dstImage.data.set(srcImage.data.subarray(0, srcWidth * srcHeight * 4), dstOffset)
for (let srcY = 0; srcY < maxHeight; srcY += 1) {
const dstY = offsetY + srcY
return dstImage
}
for (let srcX = 0; srcX < maxWidth; srcX += 1) {
const dstX = offsetX + srcX
// Since each pixel is composed of 4 values (RGBA) we multiply each index by 4.
const dstIndex = (dstY * dstImage.width + dstX) * 4
const srcIndex = (srcY * srcImage.width + srcX) * 4
dstImage.data[dstIndex] = srcImage.data[srcIndex]
dstImage.data[dstIndex + 1] = srcImage.data[srcIndex + 1]
dstImage.data[dstIndex + 2] = srcImage.data[srcIndex + 2]
dstImage.data[dstIndex + 3] = srcImage.data[srcIndex + 3]
}
const chunkLength = srcWidth * 4
for (let chunk = 0; chunk < srcHeight; ++chunk) {
const srcOffset = chunk * srcImage.width * 4
const dstOffset = ((dstY + chunk) * dstImage.width + dstX) * 4
dstImage.data.set(srcImage.data.subarray(srcOffset, srcOffset + chunkLength), dstOffset)
}

@@ -234,0 +247,0 @@

@@ -31,2 +31,10 @@ const assert = require('assert')

it('should crop a big image without heap overflow', async () => {
const actual = await makeImage({width: 1000, height: 50000})
.crop({x: 0, y: 0, width: 1000, height: 49500})
.then(image => image.toObject())
assert.strictEqual(actual.width, 1000)
assert.strictEqual(actual.height, 49500)
})
it('should scale', async () => {

@@ -48,2 +56,10 @@ const actual = await makeImage('./test/fixtures/image/house.png')

it('should rotate a big image without heap overflow', async () => {
const actual = await makeImage({width: 1000, height: 50000})
.rotate(270)
.then(image => image.toObject())
assert.strictEqual(actual.width, 50000)
assert.strictEqual(actual.height, 1000)
})
it('should copy one image to another', async () => {

@@ -58,2 +74,11 @@ const image = await makeImage('./test/fixtures/image/house.png').toObject()

})
it('should copy a big image without heap overflow', async () => {
const source = await makeImage({width: 1000, height: 50000}).toObject()
const actual = await makeImage({width: 1000, height: 50000})
.copy(source, {x: 100, y: 500})
.then(image => image.toObject())
assert.strictEqual(actual.width, 1000)
assert.strictEqual(actual.height, 50000)
})
})

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