yeet
This commit is contained in:
9
node_modules/image-size/LICENSE
generated
vendored
Normal file
9
node_modules/image-size/LICENSE
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2017 Aditya Yadav, http://netroy.in
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
126
node_modules/image-size/Readme.md
generated
vendored
Normal file
126
node_modules/image-size/Readme.md
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
# image-size
|
||||
|
||||
[](https://www.npmjs.com/package/image-size)
|
||||
[](https://travis-ci.org/image-size/image-size)
|
||||
[](http://npm-stat.com/charts.html?package=image-size&author=&from=&to=)
|
||||
[](https://coveralls.io/github/image-size/image-size?branch=master)
|
||||
[](https://david-dm.org/image-size/image-size#info=devDependencies)
|
||||
|
||||
A [Node](https://nodejs.org/en/) module to get dimensions of any image file
|
||||
|
||||
## Supported formats
|
||||
|
||||
* BMP
|
||||
* CUR
|
||||
* GIF
|
||||
* ICNS
|
||||
* ICO
|
||||
* JPEG
|
||||
* PNG
|
||||
* PSD
|
||||
* TIFF
|
||||
* WebP
|
||||
* SVG
|
||||
* DDS
|
||||
|
||||
### Upcoming
|
||||
|
||||
* SWF
|
||||
|
||||
## Programmatic Usage
|
||||
|
||||
```
|
||||
npm install image-size --save
|
||||
```
|
||||
|
||||
### Synchronous
|
||||
|
||||
```javascript
|
||||
var sizeOf = require('image-size');
|
||||
var dimensions = sizeOf('images/funny-cats.png');
|
||||
console.log(dimensions.width, dimensions.height);
|
||||
```
|
||||
|
||||
### Asynchronous
|
||||
|
||||
```javascript
|
||||
var sizeOf = require('image-size');
|
||||
sizeOf('images/funny-cats.png', function (err, dimensions) {
|
||||
console.log(dimensions.width, dimensions.height);
|
||||
});
|
||||
```
|
||||
NOTE: The asynchronous version doesn't work if the input is a Buffer. Use synchronous version instead.
|
||||
|
||||
### Using promises (node 8.x)
|
||||
```javascript
|
||||
var { promisify } = require('util');
|
||||
var sizeOf = promisify(require('image-size'));
|
||||
sizeOf('images/funny-cats.png')
|
||||
.then(dimensions => { console.log(dimensions.width, dimensions.height); })
|
||||
.catch(err => console.error(err));
|
||||
```
|
||||
|
||||
### Async/Await (Typescript & ES7)
|
||||
```javascript
|
||||
var { promisify } = require('util');
|
||||
var sizeOf = promisify(require('image-size'));
|
||||
try {
|
||||
const dimensions = await sizeOf('images/funny-cats.png');
|
||||
console.log(dimensions.width, dimensions.height);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
```
|
||||
|
||||
### Multi-size
|
||||
|
||||
If the target file is an icon (.ico) or a cursor (.cur), the `width` and `height` will be the ones of the first found image.
|
||||
|
||||
An additional `images` array is available and returns the dimensions of all the available images
|
||||
|
||||
```javascript
|
||||
var sizeOf = require('image-size');
|
||||
var images = sizeOf('images/multi-size.ico').images;
|
||||
for (const dimensions of images) {
|
||||
console.log(dimensions.width, dimensions.height);
|
||||
}
|
||||
```
|
||||
|
||||
### Using a URL
|
||||
|
||||
```javascript
|
||||
var url = require('url');
|
||||
var http = require('http');
|
||||
|
||||
var sizeOf = require('image-size');
|
||||
|
||||
var imgUrl = 'http://my-amazing-website.com/image.jpeg';
|
||||
var options = url.parse(imgUrl);
|
||||
|
||||
http.get(options, function (response) {
|
||||
var chunks = [];
|
||||
response.on('data', function (chunk) {
|
||||
chunks.push(chunk);
|
||||
}).on('end', function() {
|
||||
var buffer = Buffer.concat(chunks);
|
||||
console.log(sizeOf(buffer));
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
You can optionally check the buffer lengths & stop downloading the image after a few kilobytes.
|
||||
**You don't need to download the entire image**
|
||||
|
||||
## Command-Line Usage (CLI)
|
||||
|
||||
```
|
||||
npm install image-size --global
|
||||
image-size image1 [image2] [image3] ...
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
not a direct port, but an attempt to have something like
|
||||
[dabble's imagesize](https://github.com/dabble/imagesize/blob/master/lib/image_size.rb) as a node module.
|
||||
|
||||
## [Contributors](Contributors.md)
|
48
node_modules/image-size/bin/image-size.js
generated
vendored
Executable file
48
node_modules/image-size/bin/image-size.js
generated
vendored
Executable file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var imageSize = require('..');
|
||||
|
||||
var files = process.argv.slice(2);
|
||||
|
||||
if (!files.length) {
|
||||
console.error('Usage: image-size image1 [image2] [image3] ...');
|
||||
process.exit(-1);
|
||||
}
|
||||
|
||||
var red = ['\x1B[31m', '\x1B[39m'];
|
||||
// var bold = ['\x1B[1m', '\x1B[22m'];
|
||||
var grey = ['\x1B[90m', '\x1B[39m'];
|
||||
var green = ['\x1B[32m', '\x1B[39m'];
|
||||
|
||||
function colorize(text, color) {
|
||||
return color[0] + text + color[1]
|
||||
}
|
||||
|
||||
files.forEach(function (image) {
|
||||
try {
|
||||
if (fs.existsSync(path.resolve(image))) {
|
||||
var size = imageSize(image);
|
||||
var greyX = colorize('x', grey);
|
||||
var greyImage = colorize(image, grey);
|
||||
(size.images || [size]).forEach(function (size) {
|
||||
var greyType = '';
|
||||
if (size.type) {
|
||||
greyType = colorize(' (' + size.type + ')', grey);
|
||||
}
|
||||
console.info(
|
||||
colorize(size.width, green) + greyX + colorize(size.height, green)
|
||||
+ ' - ' + greyImage + greyType
|
||||
);
|
||||
});
|
||||
} else {
|
||||
console.error('file doesn\'t exist - ', image);
|
||||
}
|
||||
} catch (e) {
|
||||
// console.error(e.stack);
|
||||
console.error(colorize(e.message, red), '-', image);
|
||||
}
|
||||
});
|
13
node_modules/image-size/lib/detector.js
generated
vendored
Normal file
13
node_modules/image-size/lib/detector.js
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var typeHandlers = require('./types');
|
||||
|
||||
module.exports = function (buffer, filepath) {
|
||||
var type, result;
|
||||
for (type in typeHandlers) {
|
||||
result = typeHandlers[type].detect(buffer, filepath);
|
||||
if (result) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
};
|
126
node_modules/image-size/lib/index.js
generated
vendored
Normal file
126
node_modules/image-size/lib/index.js
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var typeHandlers = require('./types');
|
||||
var detector = require('./detector');
|
||||
|
||||
// Maximum buffer size, with a default of 512 kilobytes.
|
||||
// TO-DO: make this adaptive based on the initial signature of the image
|
||||
var MaxBufferSize = 512*1024;
|
||||
|
||||
/**
|
||||
* Return size information based on a buffer
|
||||
*
|
||||
* @param {Buffer} buffer
|
||||
* @param {String} filepath
|
||||
* @returns {Object}
|
||||
*/
|
||||
function lookup (buffer, filepath) {
|
||||
// detect the file type.. don't rely on the extension
|
||||
var type = detector(buffer, filepath);
|
||||
|
||||
// find an appropriate handler for this file type
|
||||
if (type in typeHandlers) {
|
||||
var size = typeHandlers[type].calculate(buffer, filepath);
|
||||
if (size !== false) {
|
||||
size.type = type;
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
// throw up, if we don't understand the file
|
||||
throw new TypeError('unsupported file type: ' + type + ' (file: ' + filepath + ')');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file into a buffer.
|
||||
*
|
||||
* The callback will be called after the process has completed. The
|
||||
* callback's first argument will be an error (or null). The second argument
|
||||
* will be the Buffer, if the operation was successful.
|
||||
*
|
||||
* @param {String} filepath
|
||||
* @param {Function} callback
|
||||
*/
|
||||
function asyncFileToBuffer (filepath, callback) {
|
||||
// open the file in read only mode
|
||||
fs.open(filepath, 'r', function (err, descriptor) {
|
||||
if (err) { return callback(err); }
|
||||
fs.fstat(descriptor, function (err, stats) {
|
||||
if (err) { return callback(err); }
|
||||
var size = stats.size;
|
||||
if (size <= 0) {
|
||||
return callback(new Error('File size is not greater than 0 —— ' + filepath));
|
||||
}
|
||||
var bufferSize = Math.min(size, MaxBufferSize);
|
||||
var buffer = new Buffer(bufferSize);
|
||||
// read first buffer block from the file, asynchronously
|
||||
fs.read(descriptor, buffer, 0, bufferSize, 0, function (err) {
|
||||
if (err) { return callback(err); }
|
||||
// close the file, we are done
|
||||
fs.close(descriptor, function (err) {
|
||||
callback(err, buffer);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously reads a file into a buffer, blocking the nodejs process.
|
||||
*
|
||||
* @param {String} filepath
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
function syncFileToBuffer (filepath) {
|
||||
// read from the file, synchronously
|
||||
var descriptor = fs.openSync(filepath, 'r');
|
||||
var size = fs.fstatSync(descriptor).size;
|
||||
var bufferSize = Math.min(size, MaxBufferSize);
|
||||
var buffer = new Buffer(bufferSize);
|
||||
fs.readSync(descriptor, buffer, 0, bufferSize, 0);
|
||||
fs.closeSync(descriptor);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Buffer|string} input - buffer or relative/absolute path of the image file
|
||||
* @param {Function} callback - optional function for async detection
|
||||
*/
|
||||
module.exports = function (input, callback) {
|
||||
|
||||
// Handle buffer input
|
||||
if (Buffer.isBuffer(input)) {
|
||||
return lookup(input);
|
||||
}
|
||||
|
||||
// input should be a string at this point
|
||||
if (typeof input !== 'string') {
|
||||
throw new TypeError('invalid invocation');
|
||||
}
|
||||
|
||||
// resolve the file path
|
||||
var filepath = path.resolve(input);
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
asyncFileToBuffer(filepath, function (err, buffer) {
|
||||
if (err) { return callback(err); }
|
||||
|
||||
// return the dimensions
|
||||
var dimensions;
|
||||
try {
|
||||
dimensions = lookup(buffer, filepath);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
callback(err, dimensions);
|
||||
});
|
||||
} else {
|
||||
var buffer = syncFileToBuffer(filepath);
|
||||
return lookup(buffer, filepath);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.types = Object.keys(typeHandlers);
|
11
node_modules/image-size/lib/readUInt.js
generated
vendored
Normal file
11
node_modules/image-size/lib/readUInt.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
// Abstract reading multi-byte unsigned integers
|
||||
function readUInt (buffer, bits, offset, isBigEndian) {
|
||||
offset = offset || 0;
|
||||
var endian = isBigEndian ? 'BE' : 'LE';
|
||||
var method = buffer['readUInt' + bits + endian];
|
||||
return method.call(buffer, offset);
|
||||
}
|
||||
|
||||
module.exports = readUInt;
|
19
node_modules/image-size/lib/types.js
generated
vendored
Normal file
19
node_modules/image-size/lib/types.js
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
// load all available handlers for browserify support
|
||||
var typeHandlers = {
|
||||
bmp: require('./types/bmp'),
|
||||
cur: require('./types/cur'),
|
||||
dds: require('./types/dds'),
|
||||
gif: require('./types/gif'),
|
||||
icns: require('./types/icns'),
|
||||
ico: require('./types/ico'),
|
||||
jpg: require('./types/jpg'),
|
||||
png: require('./types/png'),
|
||||
psd: require('./types/psd'),
|
||||
svg: require('./types/svg'),
|
||||
tiff: require('./types/tiff'),
|
||||
webp: require('./types/webp'),
|
||||
};
|
||||
|
||||
module.exports = typeHandlers;
|
17
node_modules/image-size/lib/types/bmp.js
generated
vendored
Normal file
17
node_modules/image-size/lib/types/bmp.js
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
function isBMP (buffer) {
|
||||
return ('BM' === buffer.toString('ascii', 0, 2));
|
||||
}
|
||||
|
||||
function calculate (buffer) {
|
||||
return {
|
||||
'width': buffer.readUInt32LE(18),
|
||||
'height': Math.abs(buffer.readInt32LE(22))
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isBMP,
|
||||
'calculate': calculate
|
||||
};
|
17
node_modules/image-size/lib/types/cur.js
generated
vendored
Normal file
17
node_modules/image-size/lib/types/cur.js
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
var TYPE_CURSOR = 2;
|
||||
|
||||
function isCUR (buffer) {
|
||||
var type;
|
||||
if (buffer.readUInt16LE(0) !== 0) {
|
||||
return false;
|
||||
}
|
||||
type = buffer.readUInt16LE(2);
|
||||
return type === TYPE_CURSOR;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isCUR,
|
||||
'calculate': require('./ico').calculate
|
||||
};
|
18
node_modules/image-size/lib/types/dds.js
generated
vendored
Normal file
18
node_modules/image-size/lib/types/dds.js
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
function isDDS(buffer){
|
||||
return buffer.readUInt32LE(0) === 0x20534444;
|
||||
}
|
||||
|
||||
function calculate(buffer){
|
||||
// read file resolution metadata
|
||||
return {
|
||||
'height': buffer.readUInt32LE(12),
|
||||
'width': buffer.readUInt32LE(16)
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isDDS,
|
||||
'calculate': calculate
|
||||
};
|
19
node_modules/image-size/lib/types/gif.js
generated
vendored
Normal file
19
node_modules/image-size/lib/types/gif.js
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
var gifRegexp = /^GIF8[79]a/;
|
||||
function isGIF (buffer) {
|
||||
var signature = buffer.toString('ascii', 0, 6);
|
||||
return (gifRegexp.test(signature));
|
||||
}
|
||||
|
||||
function calculate(buffer) {
|
||||
return {
|
||||
'width': buffer.readUInt16LE(6),
|
||||
'height': buffer.readUInt16LE(8)
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isGIF,
|
||||
'calculate': calculate
|
||||
};
|
122
node_modules/image-size/lib/types/icns.js
generated
vendored
Normal file
122
node_modules/image-size/lib/types/icns.js
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* ICNS Header
|
||||
*
|
||||
* | Offset | Size | Purpose |
|
||||
* | 0 | 4 | Magic literal, must be "icns" (0x69, 0x63, 0x6e, 0x73) |
|
||||
* | 4 | 4 | Length of file, in bytes, msb first. |
|
||||
*
|
||||
**/
|
||||
var SIZE_HEADER = 4 + 4; // 8
|
||||
var FILE_LENGTH_OFFSET = 4; // MSB => BIG ENDIAN
|
||||
|
||||
/**
|
||||
* Image Entry
|
||||
*
|
||||
* | Offset | Size | Purpose |
|
||||
* | 0 | 4 | Icon type, see OSType below. |
|
||||
* | 4 | 4 | Length of data, in bytes (including type and length), msb first. |
|
||||
* | 8 | n | Icon data |
|
||||
*
|
||||
**/
|
||||
var ENTRY_LENGTH_OFFSET = 4; // MSB => BIG ENDIAN
|
||||
|
||||
function isICNS (buffer) {
|
||||
return ('icns' === buffer.toString('ascii', 0, 4));
|
||||
}
|
||||
|
||||
var ICON_TYPE_SIZE = {
|
||||
ICON: 32,
|
||||
'ICN#': 32,
|
||||
// m => 16 x 16
|
||||
'icm#': 16,
|
||||
icm4: 16,
|
||||
icm8: 16,
|
||||
// s => 16 x 16
|
||||
'ics#': 16,
|
||||
ics4: 16,
|
||||
ics8: 16,
|
||||
is32: 16,
|
||||
s8mk: 16,
|
||||
icp4: 16,
|
||||
// l => 32 x 32
|
||||
icl4: 32,
|
||||
icl8: 32,
|
||||
il32: 32,
|
||||
l8mk: 32,
|
||||
icp5: 32,
|
||||
ic11: 32,
|
||||
// h => 48 x 48
|
||||
ich4: 48,
|
||||
ich8: 48,
|
||||
ih32: 48,
|
||||
h8mk: 48,
|
||||
// . => 64 x 64
|
||||
icp6: 64,
|
||||
ic12: 32,
|
||||
// t => 128 x 128
|
||||
it32: 128,
|
||||
t8mk: 128,
|
||||
ic07: 128,
|
||||
// . => 256 x 256
|
||||
ic08: 256,
|
||||
ic13: 256,
|
||||
// . => 512 x 512
|
||||
ic09: 512,
|
||||
ic14: 512,
|
||||
// . => 1024 x 1024
|
||||
ic10: 1024,
|
||||
};
|
||||
|
||||
function readImageHeader(buffer, imageOffset) {
|
||||
var imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET;
|
||||
// returns [type, length]
|
||||
return [
|
||||
buffer.toString('ascii', imageOffset, imageLengthOffset),
|
||||
buffer.readUInt32BE(imageLengthOffset)
|
||||
];
|
||||
}
|
||||
|
||||
function getImageSize(type) {
|
||||
var size = ICON_TYPE_SIZE[type];
|
||||
return { width: size, height: size, type: type };
|
||||
}
|
||||
|
||||
function calculate (buffer) {
|
||||
var
|
||||
bufferLength = buffer.length,
|
||||
imageOffset = SIZE_HEADER,
|
||||
fileLength = buffer.readUInt32BE(FILE_LENGTH_OFFSET),
|
||||
imageHeader,
|
||||
imageSize,
|
||||
result;
|
||||
|
||||
imageHeader = readImageHeader(buffer, imageOffset);
|
||||
imageSize = getImageSize(imageHeader[0]);
|
||||
imageOffset += imageHeader[1];
|
||||
|
||||
if (imageOffset === fileLength) {
|
||||
return imageSize;
|
||||
}
|
||||
|
||||
result = {
|
||||
width: imageSize.width,
|
||||
height: imageSize.height,
|
||||
images: [imageSize]
|
||||
};
|
||||
|
||||
while (imageOffset < fileLength && imageOffset < bufferLength) {
|
||||
imageHeader = readImageHeader(buffer, imageOffset);
|
||||
imageSize = getImageSize(imageHeader[0]);
|
||||
imageOffset += imageHeader[1];
|
||||
result.images.push(imageSize);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isICNS,
|
||||
'calculate': calculate
|
||||
};
|
81
node_modules/image-size/lib/types/ico.js
generated
vendored
Normal file
81
node_modules/image-size/lib/types/ico.js
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
'use strict';
|
||||
|
||||
var TYPE_ICON = 1;
|
||||
|
||||
/**
|
||||
* ICON Header
|
||||
*
|
||||
* | Offset | Size | Purpose |
|
||||
* | 0 | 2 | Reserved. Must always be 0. |
|
||||
* | 2 | 2 | Image type: 1 for icon (.ICO) image, 2 for cursor (.CUR) image. Other values are invalid. |
|
||||
* | 4 | 2 | Number of images in the file. |
|
||||
*
|
||||
**/
|
||||
var SIZE_HEADER = 2 + 2 + 2; // 6
|
||||
|
||||
/**
|
||||
* Image Entry
|
||||
*
|
||||
* | Offset | Size | Purpose |
|
||||
* | 0 | 1 | Image width in pixels. Can be any number between 0 and 255. Value 0 means width is 256 pixels. |
|
||||
* | 1 | 1 | Image height in pixels. Can be any number between 0 and 255. Value 0 means height is 256 pixels. |
|
||||
* | 2 | 1 | Number of colors in the color palette. Should be 0 if the image does not use a color palette. |
|
||||
* | 3 | 1 | Reserved. Should be 0. |
|
||||
* | 4 | 2 | ICO format: Color planes. Should be 0 or 1. |
|
||||
* | | | CUR format: The horizontal coordinates of the hotspot in number of pixels from the left. |
|
||||
* | 6 | 2 | ICO format: Bits per pixel. |
|
||||
* | | | CUR format: The vertical coordinates of the hotspot in number of pixels from the top. |
|
||||
* | 8 | 4 | The size of the image's data in bytes |
|
||||
* | 12 | 4 | The offset of BMP or PNG data from the beginning of the ICO/CUR file |
|
||||
*
|
||||
**/
|
||||
var SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4; // 16
|
||||
|
||||
function isICO (buffer) {
|
||||
var type;
|
||||
if (buffer.readUInt16LE(0) !== 0) {
|
||||
return false;
|
||||
}
|
||||
type = buffer.readUInt16LE(2);
|
||||
return type === TYPE_ICON;
|
||||
}
|
||||
|
||||
function getSizeFromOffset(buffer, offset) {
|
||||
var value = buffer.readUInt8(offset);
|
||||
return value === 0 ? 256 : value;
|
||||
}
|
||||
|
||||
function getImageSize(buffer, imageIndex) {
|
||||
var offset = SIZE_HEADER + (imageIndex * SIZE_IMAGE_ENTRY);
|
||||
return {
|
||||
'width': getSizeFromOffset(buffer, offset),
|
||||
'height': getSizeFromOffset(buffer, offset + 1)
|
||||
};
|
||||
}
|
||||
|
||||
function calculate (buffer) {
|
||||
var
|
||||
nbImages = buffer.readUInt16LE(4),
|
||||
result = getImageSize(buffer, 0),
|
||||
imageIndex;
|
||||
|
||||
if (nbImages === 1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.images = [{
|
||||
width: result.width,
|
||||
height: result.height
|
||||
}];
|
||||
|
||||
for (imageIndex = 1; imageIndex < nbImages; imageIndex += 1) {
|
||||
result.images.push(getImageSize(buffer, imageIndex));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isICO,
|
||||
'calculate': calculate
|
||||
};
|
62
node_modules/image-size/lib/types/jpg.js
generated
vendored
Normal file
62
node_modules/image-size/lib/types/jpg.js
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
// NOTE: we only support baseline and progressive JPGs here
|
||||
// due to the structure of the loader class, we only get a buffer
|
||||
// with a maximum size of 4096 bytes. so if the SOF marker is outside
|
||||
// if this range we can't detect the file size correctly.
|
||||
|
||||
function isJPG (buffer) { //, filepath
|
||||
var SOIMarker = buffer.toString('hex', 0, 2);
|
||||
return ('ffd8' === SOIMarker);
|
||||
}
|
||||
|
||||
function extractSize (buffer, i) {
|
||||
return {
|
||||
'height' : buffer.readUInt16BE(i),
|
||||
'width' : buffer.readUInt16BE(i + 2)
|
||||
};
|
||||
}
|
||||
|
||||
function validateBuffer (buffer, i) {
|
||||
// index should be within buffer limits
|
||||
if (i > buffer.length) {
|
||||
throw new TypeError('Corrupt JPG, exceeded buffer limits');
|
||||
}
|
||||
// Every JPEG block must begin with a 0xFF
|
||||
if (buffer[i] !== 0xFF) {
|
||||
throw new TypeError('Invalid JPG, marker table corrupted');
|
||||
}
|
||||
}
|
||||
|
||||
function calculate (buffer) {
|
||||
|
||||
// Skip 4 chars, they are for signature
|
||||
buffer = buffer.slice(4);
|
||||
|
||||
var i, next;
|
||||
while (buffer.length) {
|
||||
// read length of the next block
|
||||
i = buffer.readUInt16BE(0);
|
||||
|
||||
// ensure correct format
|
||||
validateBuffer(buffer, i);
|
||||
|
||||
// 0xFFC0 is baseline standard(SOF)
|
||||
// 0xFFC1 is baseline optimized(SOF)
|
||||
// 0xFFC2 is progressive(SOF2)
|
||||
next = buffer[i + 1];
|
||||
if (next === 0xC0 || next === 0xC1 || next === 0xC2) {
|
||||
return extractSize(buffer, i + 5);
|
||||
}
|
||||
|
||||
// move to the next block
|
||||
buffer = buffer.slice(i + 2);
|
||||
}
|
||||
|
||||
throw new TypeError('Invalid JPG, no size found');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isJPG,
|
||||
'calculate': calculate
|
||||
};
|
38
node_modules/image-size/lib/types/png.js
generated
vendored
Normal file
38
node_modules/image-size/lib/types/png.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
var pngSignature = 'PNG\r\n\x1a\n';
|
||||
var pngImageHeaderChunkName = 'IHDR';
|
||||
|
||||
// Used to detect "fried" png's: http://www.jongware.com/pngdefry.html
|
||||
var pngFriedChunkName = 'CgBI';
|
||||
|
||||
function isPNG (buffer) {
|
||||
if (pngSignature === buffer.toString('ascii', 1, 8)) {
|
||||
var chunkName = buffer.toString('ascii', 12, 16);
|
||||
if (chunkName === pngFriedChunkName) {
|
||||
chunkName = buffer.toString('ascii', 28, 32);
|
||||
}
|
||||
if (chunkName !== pngImageHeaderChunkName) {
|
||||
throw new TypeError('invalid png');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function calculate (buffer) {
|
||||
if (buffer.toString('ascii', 12, 16) === pngFriedChunkName) {
|
||||
return {
|
||||
'width': buffer.readUInt32BE(32),
|
||||
'height': buffer.readUInt32BE(36)
|
||||
};
|
||||
}
|
||||
return {
|
||||
'width': buffer.readUInt32BE(16),
|
||||
'height': buffer.readUInt32BE(20)
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isPNG,
|
||||
'calculate': calculate
|
||||
};
|
17
node_modules/image-size/lib/types/psd.js
generated
vendored
Normal file
17
node_modules/image-size/lib/types/psd.js
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
function isPSD (buffer) {
|
||||
return ('8BPS' === buffer.toString('ascii', 0, 4));
|
||||
}
|
||||
|
||||
function calculate (buffer) {
|
||||
return {
|
||||
'width': buffer.readUInt32BE(18),
|
||||
'height': buffer.readUInt32BE(14)
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isPSD,
|
||||
'calculate': calculate
|
||||
};
|
78
node_modules/image-size/lib/types/svg.js
generated
vendored
Normal file
78
node_modules/image-size/lib/types/svg.js
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
'use strict';
|
||||
|
||||
var svgReg = /<svg[^>]+[^>]*>/;
|
||||
function isSVG (buffer) {
|
||||
return svgReg.test(buffer);
|
||||
}
|
||||
|
||||
var extractorRegExps = {
|
||||
'root': /<svg\s[^>]+>/,
|
||||
'width': /\bwidth=(['"])([^%]+?)\1/,
|
||||
'height': /\bheight=(['"])([^%]+?)\1/,
|
||||
'viewbox': /\bviewBox=(['"])(.+?)\1/
|
||||
};
|
||||
|
||||
function parseViewbox (viewbox) {
|
||||
var bounds = viewbox.split(' ');
|
||||
return {
|
||||
'width': parseInt(bounds[2], 10),
|
||||
'height': parseInt(bounds[3], 10)
|
||||
};
|
||||
}
|
||||
|
||||
function parseAttributes (root) {
|
||||
var width = root.match(extractorRegExps.width);
|
||||
var height = root.match(extractorRegExps.height);
|
||||
var viewbox = root.match(extractorRegExps.viewbox);
|
||||
return {
|
||||
'width': width && parseInt(width[2], 10),
|
||||
'height': height && parseInt(height[2], 10),
|
||||
'viewbox': viewbox && parseViewbox(viewbox[2])
|
||||
};
|
||||
}
|
||||
|
||||
function calculateByDimensions (attrs) {
|
||||
return {
|
||||
'width': attrs.width,
|
||||
'height': attrs.height
|
||||
};
|
||||
}
|
||||
|
||||
function calculateByViewbox (attrs) {
|
||||
var ratio = attrs.viewbox.width / attrs.viewbox.height;
|
||||
if (attrs.width) {
|
||||
return {
|
||||
'width': attrs.width,
|
||||
'height': Math.floor(attrs.width / ratio)
|
||||
};
|
||||
}
|
||||
if (attrs.height) {
|
||||
return {
|
||||
'width': Math.floor(attrs.height * ratio),
|
||||
'height': attrs.height
|
||||
};
|
||||
}
|
||||
return {
|
||||
'width': attrs.viewbox.width,
|
||||
'height': attrs.viewbox.height
|
||||
};
|
||||
}
|
||||
|
||||
function calculate (buffer) {
|
||||
var root = buffer.toString('utf8').match(extractorRegExps.root);
|
||||
if (root) {
|
||||
var attrs = parseAttributes(root[0]);
|
||||
if (attrs.width && attrs.height) {
|
||||
return calculateByDimensions(attrs);
|
||||
}
|
||||
if (attrs.viewbox) {
|
||||
return calculateByViewbox(attrs);
|
||||
}
|
||||
}
|
||||
throw new TypeError('invalid svg');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isSVG,
|
||||
'calculate': calculate
|
||||
};
|
120
node_modules/image-size/lib/types/tiff.js
generated
vendored
Normal file
120
node_modules/image-size/lib/types/tiff.js
generated
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
'use strict';
|
||||
|
||||
// based on http://www.compix.com/fileformattif.htm
|
||||
// TO-DO: support big-endian as well
|
||||
|
||||
var fs = require('fs');
|
||||
var readUInt = require('../readUInt');
|
||||
|
||||
function isTIFF (buffer) {
|
||||
var hex4 = buffer.toString('hex', 0, 4);
|
||||
return ('49492a00' === hex4 || '4d4d002a' === hex4);
|
||||
}
|
||||
|
||||
// Read IFD (image-file-directory) into a buffer
|
||||
function readIFD (buffer, filepath, isBigEndian) {
|
||||
|
||||
var ifdOffset = readUInt(buffer, 32, 4, isBigEndian);
|
||||
|
||||
// read only till the end of the file
|
||||
var bufferSize = 1024;
|
||||
var fileSize = fs.statSync(filepath).size;
|
||||
if (ifdOffset + bufferSize > fileSize) {
|
||||
bufferSize = fileSize - ifdOffset - 10;
|
||||
}
|
||||
|
||||
// populate the buffer
|
||||
var endBuffer = new Buffer(bufferSize);
|
||||
var descriptor = fs.openSync(filepath, 'r');
|
||||
fs.readSync(descriptor, endBuffer, 0, bufferSize, ifdOffset);
|
||||
|
||||
// var ifdLength = readUInt(endBuffer, 16, 0, isBigEndian);
|
||||
var ifdBuffer = endBuffer.slice(2); //, 2 + 12 * ifdLength);
|
||||
return ifdBuffer;
|
||||
}
|
||||
|
||||
// TIFF values seem to be messed up on Big-Endian, this helps
|
||||
function readValue (buffer, isBigEndian) {
|
||||
var low = readUInt(buffer, 16, 8, isBigEndian);
|
||||
var high = readUInt(buffer, 16, 10, isBigEndian);
|
||||
return (high << 16) + low;
|
||||
}
|
||||
|
||||
// move to the next tag
|
||||
function nextTag (buffer) {
|
||||
if (buffer.length > 24) {
|
||||
return buffer.slice(12);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract IFD tags from TIFF metadata
|
||||
/* eslint-disable complexity */
|
||||
function extractTags (buffer, isBigEndian) {
|
||||
var tags = {};
|
||||
var code, type, length;
|
||||
|
||||
while (buffer && buffer.length) {
|
||||
code = readUInt(buffer, 16, 0, isBigEndian);
|
||||
type = readUInt(buffer, 16, 2, isBigEndian);
|
||||
length = readUInt(buffer, 32, 4, isBigEndian);
|
||||
|
||||
// 0 means end of IFD
|
||||
if (code === 0) {
|
||||
break;
|
||||
} else {
|
||||
// 256 is width, 257 is height
|
||||
// if (code === 256 || code === 257) {
|
||||
if (length === 1 && (type === 3 || type === 4)) {
|
||||
tags[code] = readValue(buffer, isBigEndian);
|
||||
}
|
||||
|
||||
// move to the next tag
|
||||
buffer = nextTag(buffer);
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
// Test if the TIFF is Big Endian or Little Endian
|
||||
function determineEndianness (buffer) {
|
||||
var signature = buffer.toString('ascii', 0, 2);
|
||||
if ('II' === signature) {
|
||||
return 'LE';
|
||||
} else if ('MM' === signature) {
|
||||
return 'BE';
|
||||
}
|
||||
}
|
||||
|
||||
function calculate (buffer, filepath) {
|
||||
|
||||
if (!filepath) {
|
||||
throw new TypeError('Tiff doesn\'t support buffer');
|
||||
}
|
||||
|
||||
// Determine BE/LE
|
||||
var isBigEndian = determineEndianness(buffer) === 'BE';
|
||||
|
||||
// read the IFD
|
||||
var ifdBuffer = readIFD(buffer, filepath, isBigEndian);
|
||||
|
||||
// extract the tags from the IFD
|
||||
var tags = extractTags(ifdBuffer, isBigEndian);
|
||||
|
||||
var width = tags[256];
|
||||
var height = tags[257];
|
||||
|
||||
if (!width || !height) {
|
||||
throw new TypeError('Invalid Tiff, missing tags');
|
||||
}
|
||||
|
||||
return {
|
||||
'width': width,
|
||||
'height': height
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isTIFF,
|
||||
'calculate': calculate
|
||||
};
|
71
node_modules/image-size/lib/types/webp.js
generated
vendored
Normal file
71
node_modules/image-size/lib/types/webp.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
'use strict';
|
||||
|
||||
// based on https://developers.google.com/speed/webp/docs/riff_container
|
||||
|
||||
function isWebP (buffer) {
|
||||
var riffHeader = 'RIFF' === buffer.toString('ascii', 0, 4);
|
||||
var webpHeader = 'WEBP' === buffer.toString('ascii', 8, 12);
|
||||
var vp8Header = 'VP8' === buffer.toString('ascii', 12, 15);
|
||||
return (riffHeader && webpHeader && vp8Header);
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
function calculate (buffer) {
|
||||
var chunkHeader = buffer.toString('ascii', 12, 16);
|
||||
buffer = buffer.slice(20, 30);
|
||||
|
||||
// Extended webp stream signature
|
||||
if (chunkHeader === 'VP8X') {
|
||||
var extendedHeader = buffer[0];
|
||||
var validStart = (extendedHeader & 0xc0) === 0;
|
||||
var validEnd = (extendedHeader & 0x01) === 0;
|
||||
if (validStart && validEnd) {
|
||||
return calculateExtended(buffer);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Lossless webp stream signature
|
||||
if (chunkHeader === 'VP8 ' && buffer[0] !== 0x2f) {
|
||||
return calculateLossy(buffer);
|
||||
}
|
||||
|
||||
// Lossy webp stream signature
|
||||
var signature = buffer.toString('hex', 3, 6);
|
||||
if (chunkHeader === 'VP8L' && signature !== '9d012a') {
|
||||
return calculateLossless(buffer);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
function calculateExtended (buffer) {
|
||||
return {
|
||||
'width': 1 + buffer.readUIntLE(4, 3),
|
||||
'height': 1 + buffer.readUIntLE(7, 3)
|
||||
};
|
||||
}
|
||||
|
||||
function calculateLossless (buffer) {
|
||||
return {
|
||||
'width': 1 + (((buffer[2] & 0x3F) << 8) | buffer[1]),
|
||||
'height': 1 + (((buffer[4] & 0xF) << 10) | (buffer[3] << 2) |
|
||||
((buffer[2] & 0xC0) >> 6))
|
||||
};
|
||||
}
|
||||
|
||||
function calculateLossy (buffer) {
|
||||
// `& 0x3fff` returns the last 14 bits
|
||||
// TO-DO: include webp scaling in the calculations
|
||||
return {
|
||||
'width': buffer.readInt16LE(6) & 0x3fff,
|
||||
'height': buffer.readInt16LE(8) & 0x3fff
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'detect': isWebP,
|
||||
'calculate': calculate
|
||||
};
|
52
node_modules/image-size/package.json
generated
vendored
Normal file
52
node_modules/image-size/package.json
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "image-size",
|
||||
"version": "0.6.3",
|
||||
"description": "get dimensions of any image file",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"bin",
|
||||
"lib"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"bin": {
|
||||
"image-size": "bin/image-size.js"
|
||||
},
|
||||
"scripts": {
|
||||
"pretest": "eslint lib specs",
|
||||
"test": "nyc mocha specs",
|
||||
"coverage": "nyc report --reporter=text-lcov | coveralls"
|
||||
},
|
||||
"repository": "image-size/image-size",
|
||||
"keywords": [
|
||||
"image",
|
||||
"size",
|
||||
"dimensions",
|
||||
"resolution",
|
||||
"width",
|
||||
"height",
|
||||
"png",
|
||||
"jpeg",
|
||||
"bmp",
|
||||
"gif",
|
||||
"psd",
|
||||
"tiff",
|
||||
"webp",
|
||||
"svg",
|
||||
"icns",
|
||||
"ico",
|
||||
"cur"
|
||||
],
|
||||
"author": "netroy <aditya@netroy.in> (http://netroy.in/)",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"coveralls": "^3.0.1",
|
||||
"eslint": "^4.19.1",
|
||||
"expect.js": "^0.3.1",
|
||||
"glob": "^7.1.1",
|
||||
"mocha": "^5.2.0",
|
||||
"nyc": "^11.9.0",
|
||||
"sinon": "^5.1.1"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user