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

jpeg-js

Package Overview
Dependencies
Maintainers
7
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jpeg-js - npm Package Compare versions

Comparing version 0.3.7 to 0.4.0

yarn.lock

42

index.d.ts
export interface RawImageData<T> {
width: number,
height: number,
data: T
width: number;
height: number;
data: T;
}

@@ -15,15 +15,23 @@

/**
* @deprecated - decode takes an object since 0.3.5
*/
export declare function decode(jpegData: BufferLike, opts: true): UintArrRet;
export declare function decode(jpegData: BufferLike, opts?: false): BufferRet;
export declare function decode(jpegData: BufferLike, opts: {
useTArray: true,
colorTransform?: boolean
}): UintArrRet;
export declare function decode(jpegData: BufferLike, opts?: {
useTArray?: false,
colorTransform?: boolean
}): BufferRet;
export declare function decode(
jpegData: BufferLike,
opts: {
useTArray: true;
colorTransform?: boolean;
formatAsRGBA?: boolean;
tolerantDecoding?: boolean;
maxResolutionInMP?: number;
maxMemoryUsageInMB?: number;
},
): UintArrRet;
export declare function decode(
jpegData: BufferLike,
opts?: {
useTArray?: false;
colorTransform?: boolean;
formatAsRGBA?: boolean;
tolerantDecoding?: boolean;
maxResolutionInMP?: number;
maxMemoryUsageInMB?: number;
},
): BufferRet;

@@ -96,3 +96,3 @@ /* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /

spectralStart, spectralEnd,
successivePrev, successive) {
successivePrev, successive, opts) {
var precision = frame.precision;

@@ -262,2 +262,5 @@ var samplesPerLine = frame.samplesPerLine;

var blockCol = mcuCol * component.h + col;
// If the block is missing and we're in tolerant mode, just skip it.
if (component.blocks[blockRow] === undefined && opts.tolerantDecoding)
return;
decode(component, component.blocks[blockRow][blockCol]);

@@ -268,2 +271,5 @@ }

var blockCol = mcu % component.blocksPerLine;
// If the block is missing and we're in tolerant mode, just skip it.
if (component.blocks[blockRow] === undefined && opts.tolerantDecoding)
return;
decode(component, component.blocks[blockRow][blockCol]);

@@ -325,2 +331,14 @@ }

if (mcu === mcuExpected) {
// Skip trailing bytes at the end of the scan - until we reach the next marker
do {
if (data[offset] === 0xFF) {
if (data[offset + 1] !== 0x00) {
break;
}
}
offset += 1;
} while (offset < data.length - 2);
}
// find marker

@@ -348,2 +366,3 @@ bitsCount = 0;

var samplesPerLine = blocksPerLine << 3;
// Only 1 used per invocation of this function and garbage collected after invocation, so no need to account for its memory footprint.
var R = new Int32Array(64), r = new Uint8Array(64);

@@ -511,2 +530,4 @@

requestMemoryAllocation(samplesPerLine * blocksPerColumn * 8);
var i, j;

@@ -550,2 +571,3 @@ for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {

parse: function parse(data) {
var maxResolutionInPixels = this.opts.maxResolutionInMP * 1000 * 1000;
var offset = 0, length = data.length;

@@ -582,3 +604,8 @@ function readUint16() {

var blocksPerColumnForMcu = mcusPerColumn * component.v;
var blocksToAllocate = blocksPerColumnForMcu * blocksPerLineForMcu;
var blocks = [];
// Each block is a Int32Array of length 64 (4 x 64 = 256 bytes)
requestMemoryAllocation(blocksToAllocate * 256);
for (var i = 0; i < blocksPerColumnForMcu; i++) {

@@ -650,2 +677,12 @@ var row = [];

// TODO APP1 - Exif
if (fileMarker === 0xFFE1) {
if (appData[0] === 0x45 &&
appData[1] === 0x78 &&
appData[2] === 0x69 &&
appData[3] === 0x66 &&
appData[4] === 0) { // 'EXIF\x00'
this.exifBuffer = appData.subarray(5, appData.length);
}
}
if (fileMarker === 0xFFEE) {

@@ -669,2 +706,3 @@ if (appData[0] === 0x41 && appData[1] === 0x64 && appData[2] === 0x6F &&

var quantizationTableSpec = data[offset++];
requestMemoryAllocation(64 * 4);
var tableData = new Int32Array(64);

@@ -699,2 +737,9 @@ if ((quantizationTableSpec >> 4) === 0) { // 8 bit values

frame.componentsOrder = [];
var pixelsInFrame = frame.scanLines * frame.samplesPerLine;
if (pixelsInFrame > maxResolutionInPixels) {
var exceededAmount = Math.ceil((pixelsInFrame - maxResolutionInPixels) / 1e6);
throw new Error(`maxResolutionInMP limit exceeded by ${exceededAmount}MP`);
}
var componentsCount = data[offset++], componentId;

@@ -725,4 +770,6 @@ var maxH = 0, maxV = 0;

var codeLengthSum = 0;
for (j = 0; j < 16; j++, offset++)
for (j = 0; j < 16; j++, offset++) {
codeLengthSum += (codeLengths[j] = data[offset]);
}
requestMemoryAllocation(16 + codeLengthSum);
var huffmanValues = new Uint8Array(codeLengthSum);

@@ -761,3 +808,3 @@ for (j = 0; j < codeLengthSum; j++, offset++)

spectralStart, spectralEnd,
successiveApproximation >> 4, successiveApproximation & 15);
successiveApproximation >> 4, successiveApproximation & 15, this.opts);
offset += processed;

@@ -820,2 +867,3 @@ break;

var dataLength = width * height * this.components.length;
requestMemoryAllocation(dataLength);
var data = new Uint8Array(dataLength);

@@ -855,4 +903,4 @@ switch (this.components.length) {

colorTransform = true;
else if (typeof this.colorTransform !== 'undefined')
colorTransform = !!this.colorTransform;
else if (typeof this.opts.colorTransform !== 'undefined')
colorTransform = !!this.opts.colorTransform;

@@ -895,4 +943,4 @@ component1 = this.components[0];

colorTransform = true;
else if (typeof this.colorTransform !== 'undefined')
colorTransform = !!this.colorTransform;
else if (typeof this.opts.colorTransform !== 'undefined')
colorTransform = !!this.opts.colorTransform;

@@ -1000,36 +1048,56 @@ component1 = this.components[0];

// We cap the amount of memory used by jpeg-js to avoid unexpected OOMs from untrusted content.
var totalBytesAllocated = 0;
var maxMemoryUsageBytes = 0;
function requestMemoryAllocation(increaseAmount = 0) {
var totalMemoryImpactBytes = totalBytesAllocated + increaseAmount;
if (totalMemoryImpactBytes > maxMemoryUsageBytes) {
var exceededAmount = Math.ceil((totalMemoryImpactBytes - maxMemoryUsageBytes) / 1024 / 1024);
throw new Error(`maxMemoryUsageInMB limit exceeded by at least ${exceededAmount}MB`);
}
totalBytesAllocated = totalMemoryImpactBytes;
}
constructor.resetMaxMemoryUsage = function (maxMemoryUsageBytes_) {
totalBytesAllocated = 0;
maxMemoryUsageBytes = maxMemoryUsageBytes_;
};
constructor.getBytesAllocated = function () {
return totalBytesAllocated;
};
constructor.requestMemoryAllocation = requestMemoryAllocation;
return constructor;
})();
module.exports = decode;
function decode(jpegData, opts) {
if (typeof module !== 'undefined') {
module.exports = decode;
} else if (typeof window !== 'undefined') {
window['jpeg-js'] = window['jpeg-js'] || {};
window['jpeg-js'].decode = decode;
}
function decode(jpegData, userOpts = {}) {
var defaultOpts = {
useTArray: false,
// "undefined" means "Choose whether to transform colors based on the image’s color model."
colorTransform: undefined,
formatAsRGBA: true
useTArray: false,
formatAsRGBA: true,
tolerantDecoding: true,
maxResolutionInMP: 100, // Don't decode more than 100 megapixels
maxMemoryUsageInMB: 512, // Don't decode if memory footprint is more than 512MB
};
if (opts) {
if (typeof opts === 'object') {
opts = {
useTArray: (typeof opts.useTArray === 'undefined' ?
defaultOpts.useTArray : opts.useTArray),
colorTransform: (typeof opts.colorTransform === 'undefined' ?
defaultOpts.colorTransform : opts.colorTransform),
formatAsRGBA: (typeof opts.formatAsRGBA === 'undefined' ?
defaultOpts.formatAsRGBA : opts.formatAsRGBA)
};
} else {
// backwards compatiblity, before 0.3.5, we only had the useTArray param
opts = defaultOpts;
opts.useTArray = true;
}
} else {
opts = defaultOpts;
}
var opts = {...defaultOpts, ...userOpts};
var arr = new Uint8Array(jpegData);
var decoder = new JpegImage();
decoder.opts = opts;
// If this constructor ever supports async decoding this will need to be done differently.
// Until then, treating as singleton limit is fine.
JpegImage.resetMaxMemoryUsage(opts.maxMemoryUsageInMB * 1024 * 1024);
decoder.parse(arr);
decoder.colorTransform = opts.colorTransform;

@@ -1039,5 +1107,7 @@ var channels = (opts.formatAsRGBA) ? 4 : 3;

try {
JpegImage.requestMemoryAllocation(bytesNeeded);
var image = {
width: decoder.width,
height: decoder.height,
exifBuffer: decoder.exifBuffer,
data: opts.useTArray ?

@@ -1044,0 +1114,0 @@ new Uint8Array(bytesNeeded) :

@@ -441,3 +441,29 @@ /*

}
function writeAPP1(exifBuffer) {
if (!exifBuffer) return;
writeWord(0xFFE1); // APP1 marker
if (exifBuffer[0] === 0x45 &&
exifBuffer[1] === 0x78 &&
exifBuffer[2] === 0x69 &&
exifBuffer[3] === 0x66) {
// Buffer already starts with EXIF, just use it directly
writeWord(exifBuffer.length + 2); // length is buffer + length itself!
} else {
// Buffer doesn't start with EXIF, write it for them
writeWord(exifBuffer.length + 5 + 2); // length is buffer + EXIF\0 + length itself!
writeByte(0x45); // E
writeByte(0x78); // X
writeByte(0x69); // I
writeByte(0x66); // F
writeByte(0); // = "EXIF",'\0'
}
for (var i = 0; i < exifBuffer.length; i++) {
writeByte(exifBuffer[i]);
}
}
function writeSOF0(width, height)

@@ -603,2 +629,3 @@ {

writeAPP0();
writeAPP1(image.exifBuffer);
writeDQT();

@@ -691,3 +718,3 @@ writeSOF0(image.width,image.height);

//return new Uint8Array(byteout);
if (typeof module === 'undefined') return new Uint8Array(byteout);
return new Buffer(byteout);

@@ -746,4 +773,8 @@

};
if (typeof module !== undefined) {
if (typeof module !== 'undefined') {
module.exports = encode;
} else if (typeof window !== 'undefined') {
window['jpeg-js'] = window['jpeg-js'] || {};
window['jpeg-js'].encode = encode;
}

@@ -750,0 +781,0 @@

{
"name": "jpeg-js",
"version": "0.3.7",
"version": "0.4.0",
"description": "A pure javascript JPEG encoder and decoder",
"main": "index.js",
"scripts": {
"test": "node_modules/.bin/tape test/*.js"
"test": "jest --testMatch=**/test/*.js"
},

@@ -30,5 +30,4 @@ "repository": {

"devDependencies": {
"redtape": "~0.1.0",
"tape": "~2.3.2"
"jest": "^25.4.0"
}
}
}

@@ -5,2 +5,4 @@ # jpeg-js

**NOTE:** this is a _synchronous_ (i.e. CPU-blocking) library that is much slower than native alternatives. If you don't need a _pure javascript_ implementation, consider using async alternatives like [sharp](http://npmjs.com/package/sharp) in node or the [Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) in the browser.
[![build status](https://secure.travis-ci.org/eugeneware/jpeg-js.png)](http://travis-ci.org/eugeneware/jpeg-js)

@@ -12,3 +14,3 @@

``` bash
```bash
$ npm install jpeg-js

@@ -23,3 +25,3 @@ ```

``` js
```js
var jpeg = require('jpeg-js');

@@ -36,9 +38,9 @@ var jpegData = fs.readFileSync('grumpycat.jpg');

To decode directly into a `Uint8Array`, pass `true` as the second argument to
To decode directly into a `Uint8Array`, pass `useTArray: true` in options
`decode`:
``` js
```js
var jpeg = require('jpeg-js');
var jpegData = fs.readFileSync('grumpycat.jpg');
var rawImageData = jpeg.decode(jpegData, true); // return as Uint8Array
var rawImageData = jpeg.decode(jpegData, {useTArray: true}); // return as Uint8Array
console.log(rawImageData);

@@ -52,14 +54,26 @@ /*

#### Decode Options
| Option | Description | Default |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| `colorTransform` | Transform alternate colorspaces like YCbCr. `undefined` means respect the default behavior encoded in metadata. | `undefined` |
| `useTArray` | Decode pixels into a typed `Uint8Array` instead of a `Buffer`. | `false` |
| `formatAsRGBA` | Decode pixels into RGBA vs. RGB. | `true` |
| `tolerantDecoding` | Be more tolerant when encountering technically invalid JPEGs. | `true` |
| `maxResolutionInMP` | The maximum resolution image that `jpeg-js` should attempt to decode in megapixels. Images larger than this resolution will throw an error instead of decoding. | `100` |
| `maxMemoryUsageInMB` | The (approximate) maximum memory that `jpeg-js` should allocate while attempting to decode the image in mebibyte. Images requiring more memory than this will throw an error instead of decoding. | `512` |
### Encoding JPEGs
``` js
```js
var jpeg = require('jpeg-js');
var width = 320, height = 180;
var width = 320,
height = 180;
var frameData = new Buffer(width * height * 4);
var i = 0;
while (i < frameData.length) {
frameData[i++] = 0xFF; // red
frameData[i++] = 0xff; // red
frameData[i++] = 0x00; // green
frameData[i++] = 0x00; // blue
frameData[i++] = 0xFF; // alpha - ignored in JPEGs
frameData[i++] = 0xff; // alpha - ignored in JPEGs
}

@@ -69,3 +83,3 @@ var rawImageData = {

width: width,
height: height
height: height,
};

@@ -80,3 +94,3 @@ var jpegImageData = jpeg.encode(rawImageData, 50);

// write to file
fs.writeFileSync("image.jpg", jpegImageData.data);
fs.writeFileSync('image.jpg', jpegImageData.data);
```

@@ -119,15 +133,15 @@

Redistribution and use in source and binary forms, with or without
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Adobe Systems Incorporated nor the names of its
contributors may be used to endorse or promote products derived from
- Neither the name of Adobe Systems Incorporated nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

@@ -138,3 +152,3 @@

THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

@@ -141,0 +155,0 @@ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

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