Socket
Socket
Sign inDemoInstall

decode-ico

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

decode-ico - npm Package Compare versions

Comparing version 0.1.6 to 0.2.0

.npmignore

93

index.js

@@ -0,1 +1,3 @@

const toDataView = require('to-data-view')
function makeDivisibleByFour (input) {

@@ -49,18 +51,9 @@ const rest = input % 4

function isPng (data, offset) {
return (
data[offset + 0] === 137 &&
data[offset + 1] === 80 &&
data[offset + 2] === 78 &&
data[offset + 3] === 71 &&
data[offset + 4] === 13 &&
data[offset + 5] === 10 &&
data[offset + 6] === 26 &&
data[offset + 7] === 10
)
function isPng (view, offset) {
return (view.getUint32(offset + 0) === 0x89504e47 && view.getUint32(offset + 4) === 0x0d0a1a0a)
}
function pngBitsPerPixel (data, offset) {
const bitDepth = data[offset + 24]
const colorType = data[offset + 25]
function pngBitsPerPixel (view, offset) {
const bitDepth = view.getUint8(offset + 24)
const colorType = view.getUint8(offset + 25)

@@ -76,11 +69,11 @@ if (colorType === 0) return bitDepth * 1

function pngWidth (data, offset) {
return data.readUInt32BE(offset + 16)
function pngWidth (view, offset) {
return view.getUint32(offset + 16, false)
}
function pngHeight (data, offset) {
return data.readUInt32BE(offset + 20)
function pngHeight (view, offset) {
return view.getUint32(offset + 20, false)
}
function decodeTrueColorBmp (data, offset, { width, height, colorDepth }) {
function decodeTrueColorBmp (data, { width, height, colorDepth }) {
if (colorDepth !== 32 && colorDepth !== 24) {

@@ -90,3 +83,3 @@ throw new Error(`A color depth of ${colorDepth} is not supported`)

const xor = new Bitmap(data, offset, { width, height, colorDepth, format: 'BGRA' })
const xor = new Bitmap(data, 0, { width, height, colorDepth, format: 'BGRA' })
const and = (colorDepth === 24)

@@ -96,3 +89,3 @@ ? new Bitmap(data, xor.offset + xor.size, { width, height, colorDepth: 1, format: 'A' })

const result = Buffer.alloc(width * height * 4)
const result = new Uint8Array(width * height * 4)

@@ -117,3 +110,3 @@ let idx = 0

function decodePaletteBmp (data, offset, { width, height, colorDepth, colorCount }) {
function decodePaletteBmp (data, { width, height, colorDepth, colorCount }) {
if (colorDepth !== 8 && colorDepth !== 4 && colorDepth !== 2 && colorDepth !== 1) {

@@ -123,7 +116,7 @@ throw new Error(`A color depth of ${colorDepth} is not supported`)

const colors = new Bitmap(data, offset, { width: colorCount, height: 1, colorDepth: 32, format: 'BGRA' })
const colors = new Bitmap(data, 0, { width: colorCount, height: 1, colorDepth: 32, format: 'BGRA' })
const xor = new Bitmap(data, colors.offset + colors.size, { width, height, colorDepth, format: 'C' })
const and = new Bitmap(data, xor.offset + xor.size, { width, height, colorDepth: 1, format: 'A' })
const result = Buffer.alloc(width * height * 4)
const result = new Uint8Array(width * height * 4)

@@ -146,7 +139,7 @@ let idx = 0

function decodeBmp ({ data, width: iconWidth, height: iconHeight }) {
const headerSize = data.readUInt32LE(0)
const bitmapWidth = (data.readUInt32LE(4) / 1) | 0
const bitmapHeight = (data.readUInt32LE(8) / 2) | 0
const colorDepth = data.readUInt16LE(14)
let colorCount = data.readUInt32LE(32)
const headerSize = data.getUint32(0, true)
const bitmapWidth = (data.getUint32(4, true) / 1) | 0
const bitmapHeight = (data.getUint32(8, true) / 2) | 0
const colorDepth = data.getUint16(14, true)
let colorCount = data.getUint32(32, true)

@@ -160,5 +153,7 @@ if (colorCount === 0 && colorDepth <= 8) {

const bitmapData = new Uint8Array(data.buffer, data.byteOffset + headerSize, data.byteLength - headerSize)
const result = colorCount
? decodePaletteBmp(data, headerSize, { width, height, colorDepth, colorCount })
: decodeTrueColorBmp(data, headerSize, { width, height, colorDepth })
? decodePaletteBmp(bitmapData, { width, height, colorDepth, colorCount })
: decodeTrueColorBmp(bitmapData, { width, height, colorDepth })

@@ -169,13 +164,13 @@ return { width, height, data: result, colorDepth }

module.exports = function decodeIco (input) {
input = Buffer.isBuffer(input) ? input : Buffer.from(input)
const view = toDataView(input)
if (input.byteLength < 6) {
if (view.byteLength < 6) {
throw new Error('Truncated header')
}
if (input.readUInt16LE(0, true) !== 0) {
if (view.getUint16(0, true) !== 0) {
throw new Error('Invalid magic bytes')
}
const type = input.readUInt16LE(2, true)
const type = view.getUint16(2, true)

@@ -186,5 +181,5 @@ if (type !== 1 && type !== 2) {

const length = input.readUInt16LE(4, true)
const length = view.getUint16(4, true)
if (input.byteLength < 6 + (16 * length)) {
if (view.byteLength < 6 + (16 * length)) {
throw new Error('Truncated image list')

@@ -194,24 +189,24 @@ }

return Array.from({ length }, (_, idx) => {
const width = input.readUInt8(6 + (16 * idx) + 0, true)
const height = input.readUInt8(6 + (16 * idx) + 1, true)
const size = input.readUInt32LE(6 + (16 * idx) + 8, true)
const offset = input.readUInt32LE(6 + (16 * idx) + 12, true)
const data = input.slice(offset, offset + size)
const width = view.getUint8(6 + (16 * idx) + 0)
const height = view.getUint8(6 + (16 * idx) + 1)
const size = view.getUint32(6 + (16 * idx) + 8, true)
const offset = view.getUint32(6 + (16 * idx) + 12, true)
const hotspot = (type !== 2 ? null : {
x: input.readUInt16LE(6 + (16 * idx) + 4, true),
y: input.readUInt16LE(6 + (16 * idx) + 6, true)
x: view.getUint16(6 + (16 * idx) + 4, true),
y: view.getUint16(6 + (16 * idx) + 6, true)
})
if (isPng(input, offset)) {
if (isPng(view, offset)) {
return {
bpp: pngBitsPerPixel(input, offset),
data,
height: pngHeight(input, offset),
bpp: pngBitsPerPixel(view, offset),
data: new Uint8Array(view.buffer, view.byteOffset + offset, size),
height: pngHeight(view, offset),
hotspot,
type: 'png',
width: pngWidth(input, offset)
width: pngWidth(view, offset)
}
}
const data = new DataView(view.buffer, view.byteOffset + offset, size)
const bmp = decodeBmp({ data, width, height })

@@ -218,0 +213,0 @@

{
"name": "decode-ico",
"version": "0.1.6",
"version": "0.2.0",
"license": "MIT",

@@ -9,2 +9,5 @@ "repository": "LinusU/decode-ico",

},
"dependencies": {
"to-data-view": "^1.0.0"
},
"devDependencies": {

@@ -11,0 +14,0 @@ "globby": "^6.1.0",

@@ -21,6 +21,6 @@ # Decode ICO

console.log(images[0])
//=> { width: 16, height: 16, type: 'bmp', data: Buffer(...), bpp: 32, hotspot: null }
//=> { width: 16, height: 16, type: 'bmp', data: Uint8Array(...), bpp: 32, hotspot: null }
console.log(images[1])
//=> { width: 32, height: 32, type: 'bmp', data: Buffer(...), bpp: 32, hotspot: null }
//=> { width: 32, height: 32, type: 'bmp', data: Uint8Array(...), bpp: 32, hotspot: null }
```

@@ -30,3 +30,3 @@

### `decodeIco(source: Buffer) => Image[]`
### `decodeIco(source: ArrayBuffer | Buffer) => Image[]`

@@ -40,7 +40,7 @@ Decodes the `.ico` file in the given buffer, and returns an array of images.

- `type: String` - The type of image, will be one of `bmp` or `png`
- `data: Buffer` - The data of the image, format depends on `type`, see below
- `bpp: Number` - The color depth of the image as the number of bits used per pixel
- `data: Uint8Array` - The data of the image, format depends on `type`, see below
- `hotspot: null | Hotspot` - If the image is a cursor (`.cur`), this is the hotspot
The format of the `data` parameter depends on the type of image. When the image is of type `bmp`, the `data` buffer will hold raw pixel data in the RGBA order, with integer values between 0 and 255 (included). When the type is `png`, the buffer will be png data.
The format of the `data` parameter depends on the type of image. When the image is of type `bmp`, the `data` array will hold raw pixel data in the RGBA order, with integer values between 0 and 255 (included). When the type is `png`, the array will be png data.

@@ -47,0 +47,0 @@ The `hotspot` property will either be `null`, or an object with an `x` and `y` property.

@@ -54,3 +54,3 @@ /* eslint-env mocha */

assert.strictEqual(imageData.data.length, expected.data.length, 'The decoded data should match the target data (length)')
assert.ok(Buffer.compare(imageData.data, expected.data) === 0, 'The decoded data should match the target data (bytes)')
assert.ok(Buffer.compare(Buffer.from(imageData.data), expected.data) === 0, 'The decoded data should match the target data (bytes)')
})

@@ -83,3 +83,3 @@ })

assert.strictEqual(imageData.data.length, expected.data.length, 'The decoded data should match the target data (length)')
assert.ok(Buffer.compare(imageData.data, expected.data) === 0, 'The decoded data should match the target data (bytes)')
assert.ok(Buffer.compare(Buffer.from(imageData.data), expected.data) === 0, 'The decoded data should match the target data (bytes)')
})

@@ -86,0 +86,0 @@ })

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