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

icojs

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

icojs - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0-alpha

browser.js

47

package.json
{
"name": "icojs",
"description": "parse ico file",
"version": "0.3.0",
"version": "0.4.0-alpha",
"author": "egy186",

@@ -10,25 +10,29 @@ "bugs": {

"dependencies": {
"canvas": "^1.2.3"
"jimp": "^0.2.21"
},
"devDependencies": {
"browserify": "^10.2.4",
"babel-preset-es2015": "^6.3.13",
"babelify": "^7.2.0",
"browserify": "^12.0.1",
"chai": "^3.0.0",
"del": "^1.2.0",
"gulp": "^3.9.0",
"gulp-coveralls": "^0.1.4",
"gulp-eslint": "^0.14.0",
"gulp-istanbul": "^0.10.0",
"gulp-mocha": "^2.1.2",
"gulp-mustache": "^1.0.2",
"gulp-sourcemaps": "^1.5.2",
"gulp-uglify": "^1.2.0",
"jsdoc": "^3.3.2",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0"
"chai-as-promised": "^5.1.0",
"eslint": "^1.10.3",
"eslint-config-eslint": "^1.0.1",
"istanbul": "^0.4.1",
"jsdoc-to-markdown": "^1.3.1",
"minifyify": "^7.1.0",
"mkdirp": "^0.5.1",
"mocha": "^2.3.4",
"rimraf": "^2.4.4"
},
"engines": {
"node": ">=4.2.3"
},
"files": [
"src",
"LICENSE",
"package.json",
"README.md"
"README.md",
"browser.js",
"index.js",
"package.json"
],

@@ -41,3 +45,3 @@ "homepage": "https://egy186.github.io/icojs",

"license": "MIT",
"main": "src/ico.js",
"main": "index.js",
"repository": {

@@ -48,5 +52,8 @@ "type": "git",

"scripts": {
"build": "gulp build",
"test": "gulp test"
"build": "mkdirp dist && browserify src/browser/index.js --debug --plugin [ minifyify --map ico.js.map --output dist/ico.js.map ] --transform babelify --standalone ICO --outfile dist/ico.js",
"clean": "rimraf coverage dist",
"doc": "jsdoc2md -f src/ico.js -t templates/README.md > README.md",
"lint": "eslint src test",
"test": "istanbul cover --root src --report lcov --dir coverage node_modules/mocha/bin/_mocha -- test/*.js"
}
}

@@ -20,3 +20,5 @@ # icojs

var arrayBuffer = new Uint8Array(fs.readFileSync('favicon.ico')).buffer;
var images = ICO.parse(arrayBuffer);
ICO.parse(arrayBuffer).then(images => {
// do something
});
```

@@ -28,4 +30,2 @@

__Prerequisite__: icojs relies on node-canvas, and you _must_ have installed __cairo__. Please see [node-canvas wiki](https://github.com/Automattic/node-canvas/wiki/_pages) for installation instructions.
```sh

@@ -47,5 +47,5 @@ npm install icojs

To fully use this library, browsers must support **JavaScript typed arrays** and **Canvas API**.
To fully use this library, browsers must support **JavaScript typed arrays**, **Canvas API** and **Promise**.
Google Chrome, Internet Explorer 11, Mozilla Firefox and Safari 7.1 support these functions.
Chrome, Edge 12, Firefox and Safari 9 support these functions.

@@ -56,43 +56,45 @@ ## Demo

<a name="ICO"></a>
## Documentation
### ICO.parse
* [ICO](#ICO)
* [.parse(buffer)](#ICO.parse) ⇒ <code>Promise.&lt;Array.&lt;Object&gt;&gt;</code>
* [.isICO(buffer)](#ICO.isICO) ⇒ <code>Boolean</code>
* [.noConflict()](#ICO.noConflict) ⇒ <code>[ICO](#ICO)</code>
<a name="ICO.parse"></a>
### ICO.parse(buffer) ⇒ <code>Promise.&lt;Array.&lt;Object&gt;&gt;</code>
Parse ICO and return some PNGs.
#### Parameters
* `buffer` **ArrayBuffer** - The ArrayBuffer object contain the TypedArray of a ICO file.
#### Returns
* **Array.&lt;Object&gt;** - Array of parsed ICO.
**Kind**: static method of <code>[ICO](#ICO)</code>
**Returns**: <code>Promise.&lt;Array.&lt;Object&gt;&gt;</code> - Resolves to array of parsed ICO.
* `width` **Number** - Image width.
* `height` **Number** - Image height.
* `bit` **Number** - Image bit depth.
* `buffer` **ArrayBuffer** - Image buffer.
* `buffer` **ArrayBuffer** - Image buffer.
### ICO.isICO
| Param | Type | Description |
| --- | --- | --- |
| buffer | <code>ArrayBuffer</code> | The ArrayBuffer object contain the TypedArray of a ICO file. |
<a name="ICO.isICO"></a>
### ICO.isICO(buffer) ⇒ <code>Boolean</code>
Check the ArrayBuffer is valid ICO.
#### Parameters
**Kind**: static method of <code>[ICO](#ICO)</code>
**Returns**: <code>Boolean</code> - True if arg is ICO.
* `buffer` **ArrayBuffer** - The ArrayBuffer object contain the TypedArray of a ICO file.
| Param | Type | Description |
| --- | --- | --- |
| buffer | <code>ArrayBuffer</code> | The ArrayBuffer object contain the TypedArray of a ICO file. |
#### Returns
* **Boolean** - True if arg is ICO.
### ICO.noConflict
<a name="ICO.noConflict"></a>
### ICO.noConflict() ⇒ <code>[ICO](#ICO)</code>
No conflict.
**Kind**: static method of <code>[ICO](#ICO)</code>
**Returns**: <code>[ICO](#ICO)</code> - `ICO` Object.
#### Returns
* **ICO** - `ICO` Object.
## License
MIT license

@@ -1,220 +0,95 @@

/* global global: false */
'use strict';
var extractOne = require('./extractone');
var PNG = require('./png');
var util = require('./util');
const extractOne = require('./extract-one');
const imageData = require('./image-data');
/**
* make 1bit image imageData.data
* @private
* @param {Object} ico should have width, height, bit, colors, xor, and
* @returns {Uint8ClampedArray} imageData.data
*/
var make1bitImageData = function (ico) {
var color;
var xor = util.to1bitArray(ico.xor);
var and = util.to1bitArray(ico.and);
var xorLine = util.toDividableBy4(ico.width * ico.bit / 8) * 8 / ico.bit;
var andLine = util.toDividableBy4(ico.width / 8) * 8;
var index = 0;
var data = new Uint8ClampedArray(ico.width * ico.height * 4);
for (var h = ico.height - 1; h >= 0; h--) {
for (var w = 0; w < ico.width; w++) {
color = ico.colors[xor[h * xorLine + w]];
data[index] = color[2];
data[index + 1] = color[1];
data[index + 2] = color[0];
data[index + 3] = and[h * andLine + w] ? 0 : 255;
index += 4;
}
}
return data;
};
const range = n => new Array(n).fill(0).map((_, i) => i);
/**
* make 4bit image imageData.data
* @private
* @param {Object} ico should have width, height, bit, colors, xor, and
* @returns {Uint8ClampedArray} imageData.data
*/
var make4bitImageData = function (ico) {
var color;
var xor = util.to4bitArray(ico.xor);
var and = util.to1bitArray(ico.and);
var xorLine = util.toDividableBy4(ico.width * ico.bit / 8) * 8 / ico.bit;
var andLine = util.toDividableBy4(ico.width / 8) * 8;
var index = 0;
var data = new Uint8ClampedArray(ico.width * ico.height * 4);
for (var h = ico.height - 1; h >= 0; h--) {
for (var w = 0; w < ico.width; w++) {
color = ico.colors[xor[h * xorLine + w]];
data[index] = color[2];
data[index + 1] = color[1];
data[index + 2] = color[0];
data[index + 3] = and[h * andLine + w] ? 0 : 255;
index += 4;
}
}
return data;
};
* @class ICO
*/
/**
* make 8bit image imageData.data
* @private
* @param {Object} ico should have width, height, bit, colors, xor, and
* @returns {Uint8ClampedArray} imageData.data
*/
var make8bitImageData = function (ico) {
var color;
var xor = new Uint8Array(ico.xor);
var and = util.to1bitArray(ico.and);
var xorLine = util.toDividableBy4(ico.width * ico.bit / 8) * 8 / ico.bit;
var andLine = util.toDividableBy4(ico.width / 8) * 8;
var index = 0;
var data = new Uint8ClampedArray(ico.width * ico.height * 4);
index = 0;
for (var h = ico.height - 1; h >= 0; h--) {
for (var w = 0; w < ico.width; w++) {
color = ico.colors[xor[h * xorLine + w]];
data[index] = color[2];
data[index + 1] = color[1];
data[index + 2] = color[0];
data[index + 3] = and[h * andLine + w] ? 0 : 255;
index += 4;
}
}
return data;
};
/**
* make 24bit image imageData.data
* @private
* @param {Object} ico should have width, height, bit, xor, and
* @returns {Uint8ClampedArray} imageData.data
*/
var make24bitImageData = function (ico) {
var xor = new Uint8Array(ico.xor);
var and = util.to1bitArray(ico.and);
var xorLine = util.toDividableBy4(ico.width * ico.bit / 8) * 8 / ico.bit;
var andLine = util.toDividableBy4(ico.width / 8) * 8;
var index = 0;
var data = new Uint8ClampedArray(ico.width * ico.height * 4);
for (var h = ico.height - 1; h >= 0; h--) {
for (var w = 0; w < ico.width; w++) {
data[index] = xor[(h * xorLine + w) * 3 + 2];
data[index + 1] = xor[(h * xorLine + w) * 3 + 1];
data[index + 2] = xor[(h * xorLine + w) * 3];
data[index + 3] = and[h * andLine + w] ? 0 : 255;
index += 4;
}
}
return data;
};
/**
* make 32bit image imageData.data
* @private
* @param {Object} ico should have width, height, bit, xor, and
* @returns {Uint8ClampedArray} imageData.data
*/
var make32bitImageData = function (ico) {
var xor = new Uint8Array(ico.xor);
var and = util.to1bitArray(ico.and);
var xorLine = util.toDividableBy4(ico.width * ico.bit / 8) * 8 / ico.bit;
var andLine = util.toDividableBy4(ico.width / 8) * 8;
var index = 0;
var data = new Uint8ClampedArray(ico.width * ico.height * 4);
for (var h = ico.height - 1; h >= 0; h--) {
for (var w = 0; w < ico.width; w++) {
data[index] = xor[(h * xorLine + w) * 4 + 2];
data[index + 1] = xor[(h * xorLine + w) * 4 + 1];
data[index + 2] = xor[(h * xorLine + w) * 4];
data[index + 3] = and[h * andLine + w] === 1 || xor[(h * xorLine + w) * 4 + 3] === 1 ? 0 : xor[(h * xorLine + w) * 4 + 3] > 1 ? xor[(h * xorLine + w) * 4 + 3] : 255;
index += 4;
}
}
return data;
};
var previousICO = global.ICO;
/**
* @class ICO
*/
var ICO = {
/**
* Parse ICO and return some PNGs.
* @param {ArrayBuffer} buffer The ArrayBuffer object contain the TypedArray of a ICO file.
* @returns {Object[]} Array of parsed ICO.
* * `width` **Number** - Image width.
* * `height` **Number** - Image height.
* * `bit` **Number** - Image bit depth.
* * `buffer` **ArrayBuffer** - Image buffer.
*/
parse: function (buffer) {
var icoDv = new DataView(buffer);
if (icoDv.getUint16(0, true) !== 0 || icoDv.getUint16(2, true) !== 1) {
throw new Error('buffer is not ico');
}
// make single image icon
var ico, data;
var icos = [];
// var idCount = icoDv.getUint16(4, true);
for (var i = 0; i < icoDv.getUint16(4, true); i++) {
ico = extractOne(buffer, i);
switch (ico.bit) {
case 1:
data = make1bitImageData(ico);
break;
case 4:
data = make4bitImageData(ico);
break;
case 8:
data = make8bitImageData(ico);
break;
case 24:
data = make24bitImageData(ico);
break;
case 32:
data = make32bitImageData(ico);
break;
const factory = config => {
const previousICO = global.ICO;
const ICO = {
/**
* Parse ICO and return some PNGs.
* @memberof ICO
* @param {ArrayBuffer} buffer The ArrayBuffer object contain the TypedArray of a ICO file.
* @returns {Promise<Object[]>} Resolves to array of parsed ICO.
* * `width` **Number** - Image width.
* * `height` **Number** - Image height.
* * `bit` **Number** - Image bit depth.
* * `buffer` **ArrayBuffer** - Image buffer.
*/
parse (buffer) {
const icoDv = new DataView(buffer);
if (icoDv.getUint16(0, true) !== 0 || icoDv.getUint16(2, true) !== 1) {
return Promise.reject(new Error('buffer is not ico'));
}
icos.push({
bit: ico.bit,
width: ico.width,
height: ico.height,
buffer: PNG.encode({
// make single image icon
// let idCount = icoDv.getUint16(4, true);
const icos = Promise.all(range(icoDv.getUint16(4, true)).map(i => {
let data;
const ico = extractOne(buffer, i);
switch (ico.bit) { // eslint-disable-line default-case
case 1:
data = imageData.from1bit(ico);
break;
case 4:
data = imageData.from4bit(ico);
break;
case 8:
data = imageData.from8bit(ico);
break;
case 24:
data = imageData.from24bit(ico);
break;
case 32:
data = imageData.from32bit(ico);
break;
}
return config.PNG.encode({
width: ico.width,
height: ico.height,
data: data
})
});
data
}).then(pngBuffer => {
return {
bit: ico.bit,
width: ico.width,
height: ico.height,
buffer: pngBuffer
};
});
}));
return icos;
},
/**
* Check the ArrayBuffer is valid ICO.
* @memberof ICO
* @param {ArrayBuffer} buffer The ArrayBuffer object contain the TypedArray of a ICO file.
* @returns {Boolean} True if arg is ICO.
*/
isICO (buffer) {
if (!(buffer instanceof ArrayBuffer)) {
return false;
}
const icoDv = new DataView(buffer);
// idReserved = icoDv.getUint16(0, true)
// idType = icoDv.getUint16(0, true)
return icoDv.getUint16(0, true) === 0 && icoDv.getUint16(2, true) === 1;
},
/**
* No conflict.
* @memberof ICO
* @returns {ICO} `ICO` Object.
*/
noConflict () {
global.ICO = previousICO;
return this;
}
return icos;
},
/**
* Check the ArrayBuffer is valid ICO.
* @param {ArrayBuffer} buffer The ArrayBuffer object contain the TypedArray of a ICO file.
* @returns {Boolean} True if arg is ICO.
*/
isICO: function (buffer) {
if (!(buffer instanceof ArrayBuffer)) {
return false;
}
var icoDv = new DataView(buffer);
// idReserved = icoDv.getUint16(0, true)
// idType = icoDv.getUint16(0, true)
return icoDv.getUint16(0, true) === 0 && icoDv.getUint16(2, true) === 1;
},
/**
* No conflict.
* @returns {ICO} `ICO` Object.
*/
noConflict: function () {
global.ICO = previousICO;
return this;
}
};
return ICO;
};
module.exports = ICO;
global.ICO = ICO;
module.exports = factory;

@@ -1,35 +0,12 @@

/* global global: false */
'use strict';
/* istanbul ignore next */
var createCanvas = global.document ? function (width, height) {
var canvas = global.document.createElement('canvas');
canvas.width = width;
canvas.height = height;
return canvas;
} : function (width, height) {
var Canvas = require('canvas');
return new Canvas(width, height);
};
const Jimp = require('jimp');
/* istanbul ignore next */
/* jshint -W079 */
var atob = global.atob ? global.atob : function (str) {
/* jshint +W079 */
var Buffer = require('buffer').Buffer;
return new Buffer(str, 'base64').toString('binary');
};
const bufferToArrayBuffer = require('./utils/buffer-to-arraybuffer');
var dataURLToArrayBuffer = function (dataURL) {
var string = atob(dataURL.replace(/.+,/, ''));
var bytes = new Uint8Array(string.length);
for (var i = 0; i < string.length; i++) {
bytes[i] = string.charCodeAt(i);
}
return bytes.buffer;
};
var PNG = {
const PNG = {
/**
* create png from imgData.data
* @param {Object} data
* @access private
* @param {Object} image data
* @param {Number} image.width img width

@@ -40,26 +17,24 @@ * @param {Number} image.height img height

*/
encode: function (image) {
var data = image.data;
var canvas = createCanvas(image.width, image.height);
var ctx = canvas.getContext('2d');
var imageData = ctx.createImageData(image.width, image.height);
var dataData = imageData.data;
for (var i = 0; i < dataData.length; i++) {
dataData[i] = data[i];
}
ctx.putImageData(imageData, 0, 0);
return dataURLToArrayBuffer(canvas.toDataURL());
encode (image) {
const data = image.data;
const jimp = new Jimp(image.width, image.height);
jimp.scan(0, 0, jimp.bitmap.width, jimp.bitmap.height, function (x, y, idx) {
this.bitmap.data[idx + 0] = data[idx + 0]; // eslint-disable-line no-invalid-this
this.bitmap.data[idx + 1] = data[idx + 1]; // eslint-disable-line no-invalid-this
this.bitmap.data[idx + 2] = data[idx + 2]; // eslint-disable-line no-invalid-this
this.bitmap.data[idx + 3] = data[idx + 3]; // eslint-disable-line no-invalid-this
});
return new Promise((resolve, reject) => {
jimp.getBuffer(Jimp.MIME_PNG, (err, buffer) => {
/* istanbul ignore if */
if (err) {
reject(err);
} else {
resolve(bufferToArrayBuffer(buffer));
}
});
});
}
/**
* create imgData.data from png
* @param {ArrayBuffer} buffer png
* @returns {Object} data
* @returns {Number} image.width
* @returns {Number} image.height
* @returns {Uint8ClampedArray} image.data
*/
/*decode: function (buffer) {
}*/
};
module.exports = PNG;
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