This commit is contained in:
2022-09-30 05:39:11 +00:00
parent 41ee9463ae
commit 4687fa49bc
11418 changed files with 1312504 additions and 0 deletions

View File

@ -0,0 +1,185 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [5.0.0] - 2019-09-14
### Changed
- Drop `any-promise`, use native, #32.
## [4.1.1] - 2019-07-11
### Fixed
- Fix streams unpipe (after 4.1.0 changes), #34.
## [4.1.0] - 2019-07-09
### Changed
- Deps bump.
- Update Travis-CI node versions to actual.
### Fixed
- Fix content ungzip from misconfigured servers, #31.
## [4.0.1] - 2019-07-08
### Fixed
- Fix regexp to ignore SVG `stroke-width` attr, #33.
## [4.0.0] - 2018-03-05
### Changed
- Roll back `got` -> `request`, see #16.
- Default timeout 30s -> 60s.
### Fixed
- Fix padding parse in jpeg, #20.
## [3.2.0] - 2017-11-22
### Changed
- Roll back `got` to 6.x due serious regressions, see #16.
Next attempt will be switching to `request` and releasing 4.0.0.
## [3.1.0] - 2017-06-08
### Changed
- Maintenance, deps bump. `got` 6.x -> 7.x. `got` timeouts may work a bit
different but should affect result.
## [3.0.0] - 2016-12-02
### Changed
- Rewrite internals to `Promise`.
- Separate options from url for http probe (old signature still supported
for compatibility).
- `err.status` -> `err.statusCode`
- remove `{ rejectUnauthorized: false }` from defaults.
- User-Agent string update.
- Replaced `request` dependency with `got` (read options description in doc).
- Retry requests on network fail.
- Switched from `readable-stream` to native `stream` (node 4+ has normal Stream3).
- Proper class for errors.
## [2.2.0] - 2016-10-26
### Added
- Add `.url` with actual image address (after redirects) for remotes.
## [2.1.1] - 2016-08-25
### Added
- Add default user agent to http requests (if not set by options), #8.
## [2.1.0] - 2016-07-14
### Changed
- Internal parsers api cleanup - switch from callbacks to events.
### Fixed
- Fixed "write after end" error under heavy load.
## [2.0.1] - 2016-07-01
### Fixed
- Fixed bug in streams cleanup condition.
## [2.0.0] - 2016-06-25
### Added
- SVG support
- Return dimention units ('px' everywhere except SVG)
### Changed
- width/height now can be float (with fractional part)
## [1.2.1] - 2016-05-30
### Fixed
- Stream: posponed callback to avoid possible races on forced stream close.
## [1.2.0] - 2016-05-28
### Added
- Added `.sync.probe()` method.
- 100% tests coverage.
### Changed
- Splited to separate files (simplify browserification).
- Faster return on positive result & faster resource release.
### Fixed
- Fix stream error handling.
## [1.1.0] - 2016-05-25
### Added
- Added promise support.
### Changed
- Use `readable-stream` instead of `stream`.
- Reorganised internal files structure & tests.
## [1.0.6] - 2016-04-13
### Fixed
- Fixed parser crashes on zero length data & offsets.
## [1.0.5] - 2015-12-15
### Changed
- Increased http request timeout to 30 seconds.
- Don't check SSL sertificates.
## [1.0.4] - 2015-09-22
### Fixed
- Fixed crash on empty JPEG markers.
## [1.0.3] - 2015-09-19
### Fixed
- Fixed catch internal exceptions from `request`.
## [1.0.2] - 2015-09-16
### Added
- Added `ECONTENT` error code for parse errors.
## [1.0.1] - 2015-09-14
### Added
- Return image length when possible.
- Support URLs in dev helper script.
## [1.0.0] - 2015-09-12
### Added
- First release.
[5.0.0]: https://github.com/nodeca/probe-image-size/compare/4.1.1...5.0.0
[4.1.1]: https://github.com/nodeca/probe-image-size/compare/4.1.0...4.1.1
[4.1.0]: https://github.com/nodeca/probe-image-size/compare/4.0.1...4.1.0
[4.0.1]: https://github.com/nodeca/probe-image-size/compare/4.0.0...4.0.1
[4.0.0]: https://github.com/nodeca/probe-image-size/compare/3.2.0...4.0.0
[3.2.0]: https://github.com/nodeca/probe-image-size/compare/3.1.0...3.2.0
[3.1.0]: https://github.com/nodeca/probe-image-size/compare/3.0.0...3.1.0
[3.0.0]: https://github.com/nodeca/probe-image-size/compare/2.2.0...3.0.0
[2.2.0]: https://github.com/nodeca/probe-image-size/compare/2.1.1...2.2.0
[2.1.1]: https://github.com/nodeca/probe-image-size/compare/2.1.0...2.1.1
[2.1.0]: https://github.com/nodeca/probe-image-size/compare/2.0.1...2.1.0
[2.0.1]: https://github.com/nodeca/probe-image-size/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/nodeca/probe-image-size/compare/1.2.1...2.0.0
[1.2.1]: https://github.com/nodeca/probe-image-size/compare/1.2.0...1.2.1
[1.2.0]: https://github.com/nodeca/probe-image-size/compare/1.1.0...1.2.0
[1.1.0]: https://github.com/nodeca/probe-image-size/compare/1.0.6...1.1.0
[1.0.6]: https://github.com/nodeca/probe-image-size/compare/1.0.5...1.0.6
[1.0.5]: https://github.com/nodeca/probe-image-size/compare/1.0.4...1.0.5
[1.0.4]: https://github.com/nodeca/probe-image-size/compare/1.0.3...1.0.4
[1.0.3]: https://github.com/nodeca/probe-image-size/compare/1.0.2...1.0.3
[1.0.2]: https://github.com/nodeca/probe-image-size/compare/1.0.1...1.0.2
[1.0.1]: https://github.com/nodeca/probe-image-size/compare/1.0.0...1.0.1
[1.0.0]: https://github.com/nodeca/probe-image-size/releases/tag/1.0.0

22
buildfiles/app/node_modules/probe-image-size/LICENSE generated vendored Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2015 Vitaly Puzrin.
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.

147
buildfiles/app/node_modules/probe-image-size/README.md generated vendored Normal file
View File

@ -0,0 +1,147 @@
probe-image-size
================
[![Build Status](https://img.shields.io/travis/nodeca/probe-image-size/master.svg?style=flat)](https://travis-ci.org/nodeca/probe-image-size)
[![NPM version](https://img.shields.io/npm/v/probe-image-size.svg?style=flat)](https://www.npmjs.org/package/probe-image-size)
[![Coverage Status](https://coveralls.io/repos/github/nodeca/probe-image-size/badge.svg?branch=master)](https://coveralls.io/github/nodeca/probe-image-size?branch=master)
> Get image size without full download. Supported image types:
> JPG, GIF, PNG, WebP, BMP, TIFF, SVG, PSD.
Key features:
- small size, no heavy dependencies
- works with remote and local data
- effective with big images (speed/memory), download minimal data from remotes
- easy to browserify (splitted to components)
Install
-------
```bash
npm install probe-image-size --save
```
Example
-------
```js
var probe = require('probe-image-size');
// Get by URL
//
probe('http://example.com/image.jpg').then(result => {
console.log(result); // =>
/*
{
width: xx,
height: yy,
type: 'jpg',
mime: 'image/jpeg',
wUnits: 'px',
hUnits: 'px',
url: 'http://example.com/image.jpg'
}
*/
});
// By URL with options
//
probe('http://example.com/image.jpg', { timeout: 5000 }).then(function (result) {
console.log(result);
});
// With callback
//
probe('http://example.com/image.jpg', function (err, result) {
console.log(result);
});
// From the stream
//
var input = require('fs').createReadStream('image.jpg');
probe(input).then(result => {
console.log(result);
// terminate input, depends on stream type,
// this example is for fs streams only.
input.destroy();
});
// From a Buffer
//
var data = require('fs').readFileSync('image.jpg');
console.log(probe.sync(data));
```
API
---
### probe(src [, options, callback]) -> Promise
`src` can be of this types:
- __String__ - URL to fetch
- __Stream__ - readable stream
`options` - HTTP only. See [`got` documentation](https://github.com/sindresorhus/got).
Defaults changed to `{ retries: 1, timeout: 30000 }`
`result` (Promise) contains:
```js
{
width: XX,
height: YY,
length: ZZ, // byte length of the file (if available, HTTP only)
type: ..., // image 'type' (usual file name extention)
mime: ..., // mime type
wUnits: 'px', // width units type ('px' by default, can be different for SVG)
hUnits: 'px', // height units type ('px' by default, can be different for SVG)
url: ..., // last url for the image in chain of redirects (if no redirects, same as src) (HTTP only)
}
```
Returned errors can be extended with 2 fields:
- `code` - equals to `ECONTENT` if the library failed to parse the file;
- `status` - equals to a HTTP status code if it receives a non-200 response.
If callback (legacy node style) provided, `Promise` will not be returned.
__Note 1.__ If you use `Stream` as source, it's your responsibility to close that
stream in callback. In other case you can get memory leak, because stream will
be left in paused state. With http requests that's not a problem - everything
is released automatically, as soon as possible.
__Note 2.__ We still support legacy v2.x signature for http probe (`src` is
Object as described in [request](https://github.com/request/request)). But it
will be deprecated in next versions.
### sync.probe(src) -> result|null
Sync version can eat arrays, typed arrays and buffers. On success it returns
the same result as async version. On fail it returns null.
__Note.__ Formats like JPEG & TIFF can store size anywhere (far from the head).
That usually does not happens, but if you need guarantees - always provide full
file content to sync methods. We strongly recommend to use async version
as memory-friendly.
Similar projects
----------------
- [image-size](https://github.com/netroy/image-size)
- [imagesize](https://github.com/arnaud-lb/imagesize.js)
Support probe-image-size
------------------------
You can support this project via [Tidelift subscription](https://tidelift.com/subscription/pkg/npm-probe-image-size?utm_source=npm-probe-image-size&utm_medium=referral&utm_campaign=readme).

83
buildfiles/app/node_modules/probe-image-size/http.js generated vendored Normal file
View File

@ -0,0 +1,83 @@
'use strict';
var ProbeError = require('./lib/common').ProbeError;
var request = require('request');
var merge = require('deepmerge');
var pkg = require('./package.json');
var probeStream = require('./stream');
var defaultAgent = pkg.name + '/' + pkg.version + '(+https://github.com/nodeca/probe-image-size)';
var defaults = {
timeout: 60000,
// retries: 1, // needed for `got` only, not supported by `request`
headers: {
'User-Agent': defaultAgent,
// Override default "gzip, deflate" header that is auto-inserted when
// request has gzip option turned on.
//
// It's done so because gzip may have large block size, and we only need
// to know a first few bytes to extract image size.
//
'Accept-Encoding': 'identity'
},
// turn gzip decompression on in case there are misconfigured servers
// that always return gzip encoded content even if not requested
gzip: true
};
module.exports = function probeHttp(src, options) {
return new Promise(function (resolve, reject) {
var stream, length, finalUrl;
try {
stream = request(merge.all([ { url: src }, defaults, options ]));
} catch (err) {
reject(err);
return;
}
stream.on('response', function (res) {
if (res.statusCode !== 200) {
var err = new ProbeError('bad status code: ' + res.statusCode, null, res.statusCode);
stream.abort();
reject(err);
return;
}
var len = res.headers['content-length'];
if (len && len.match(/^\d+$/)) length = +len;
finalUrl = res.request.uri.href;
probeStream(stream)
.then(function (result) {
if (length) result.length = length;
result.url = finalUrl;
resolve(result);
})
.catch(reject)
.then(function () { stream.abort(); });
});
stream.on('error', function (err) {
/* This check needed for `got` only, because it returns 404 as error.
if (err.statusCode) {
reject(new ProbeError('bad status code: ' + err.statusCode, null, err.statusCode));
return;
}*/
reject(err);
});
});
};
module.exports.parsers = require('./lib/parsers_stream');

52
buildfiles/app/node_modules/probe-image-size/index.js generated vendored Normal file
View File

@ -0,0 +1,52 @@
'use strict';
var probeStream = require('./stream');
var probeHttp = require('./http');
var nextTick = require('next-tick');
var merge = require('deepmerge');
/* eslint-disable consistent-return */
module.exports = function get_image_size(src, options, callback) {
if (typeof src.on === 'function' && typeof src.emit === 'function') {
// looks like an EventEmitter, treating it as a stream
callback = options;
if (!callback) return probeStream(src);
probeStream(src)
.then(function (size) { nextTick(callback.bind(null, null, size)); })
.catch(function (err) { nextTick(callback.bind(null, err)); });
return;
}
// HTTP (not stream)
if (typeof src === 'string') {
// `probe(string [, options, callback])`
if (typeof options === 'function') {
callback = options;
options = {};
}
options = options || {};
} else {
// Legacy style, `probe(object [, callback])`
callback = options;
options = merge({}, src);
src = options.url;
delete options.url;
}
if (!callback) return probeHttp(src, options);
probeHttp(src, options)
.then(function (size) { nextTick(callback.bind(null, null, size)); })
.catch(function (err) { nextTick(callback.bind(null, err)); });
};
module.exports.parsers = require('./lib/parsers_stream');
module.exports.sync = require('./sync');
module.exports.Error = require('./lib/common').ProbeError;

View File

@ -0,0 +1,83 @@
'use strict';
var Transform = require('stream').Transform;
var streamParser = require('stream-parser');
var inherits = require('util').inherits;
function ParserStream() {
Transform.call(this, { readableObjectMode: true });
}
inherits(ParserStream, Transform);
streamParser(ParserStream.prototype);
exports.ParserStream = ParserStream;
exports.sliceEq = function (src, start, dest) {
for (var i = start, j = 0; j < dest.length;) {
if (src[i++] !== dest[j++]) return false;
}
return true;
};
exports.str2arr = function (str, format) {
var arr = [], i = 0;
if (format && format === 'hex') {
while (i < str.length) {
arr.push(parseInt(str.slice(i, i + 2), 16));
i += 2;
}
} else {
for (; i < str.length; i++) {
/* eslint-disable no-bitwise */
arr.push(str.charCodeAt(i) & 0xFF);
}
}
return arr;
};
exports.readUInt16LE = function (data, offset) {
return data[offset] | (data[offset + 1] << 8);
};
exports.readUInt16BE = function (data, offset) {
return data[offset + 1] | (data[offset] << 8);
};
exports.readUInt32LE = function (data, offset) {
return data[offset] |
(data[offset + 1] << 8) |
(data[offset + 2] << 16) |
(data[offset + 3] * 0x1000000);
};
exports.readUInt32BE = function (data, offset) {
return data[offset + 3] |
(data[offset + 2] << 8) |
(data[offset + 1] << 16) |
(data[offset] * 0x1000000);
};
function ProbeError(message, code, statusCode) {
Error.call(this);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = message;
if (code) this.code = code;
if (statusCode) this.statusCode = statusCode;
}
// Inherit from Error
require('inherits')(ProbeError, Error);
exports.ProbeError = ProbeError;

View File

@ -0,0 +1,36 @@
'use strict';
var ParserStream = require('../common').ParserStream;
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var SIG_BM = str2arr('BM');
module.exports = function () {
var parser = new ParserStream();
parser._bytes(26, function (data) {
parser._skipBytes(Infinity);
if (!sliceEq(data, 0, SIG_BM)) {
parser.push(null);
return;
}
parser.push({
width: data.readUInt16LE(18),
height: data.readUInt16LE(22),
type: 'bmp',
mime: 'image/bmp',
wUnits: 'px',
hUnits: 'px'
});
parser.push(null);
});
return parser;
};

View File

@ -0,0 +1,37 @@
'use strict';
var ParserStream = require('../common').ParserStream;
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var SIG_GIF87a = str2arr('GIF87a');
var SIG_GIF89a = str2arr('GIF89a');
module.exports = function () {
var parser = new ParserStream();
parser._bytes(10, function (data) {
parser._skipBytes(Infinity);
if (!sliceEq(data, 0, SIG_GIF87a) && !sliceEq(data, 0, SIG_GIF89a)) {
parser.push(null);
return;
}
parser.push({
width: data.readUInt16LE(6),
height: data.readUInt16LE(8),
type: 'gif',
mime: 'image/gif',
wUnits: 'px',
hUnits: 'px'
});
parser.push(null);
});
return parser;
};

View File

@ -0,0 +1,117 @@
'use strict';
var ParserStream = require('../common').ParserStream;
// part of parseJpegMarker called after skipping initial FF
function parseJpegMarker_afterFF(parser, callback) {
parser._bytes(1, function (data) {
var code = data[0];
if (code === 0xFF) {
// padding byte, skip it
parseJpegMarker_afterFF(parser, callback);
return;
}
// standalone markers, according to JPEG 1992,
// http://www.w3.org/Graphics/JPEG/itu-t81.pdf, see Table B.1
if ((0xD0 <= code && code <= 0xD9) || code === 0x01) {
callback(code, 0);
return;
}
// the rest of the unreserved markers
if (0xC0 <= code && code <= 0xFE) {
parser._bytes(2, function (length) {
callback(code, length.readUInt16BE(0) - 2);
});
return;
}
// unknown markers
callback();
});
}
function parseJpegMarker(parser, callback) {
parser._bytes(1, function (data) {
if (data[0] !== 0xFF) {
// not a JPEG marker
callback();
return;
}
parseJpegMarker_afterFF(parser, callback);
});
}
function getJpegSize(parser) {
parseJpegMarker(parser, function (code, length) {
if (!code || length < 0) {
// invalid jpeg
parser._skipBytes(Infinity);
parser.push(null);
return;
}
if (code === 0xD9 /* EOI */ || code === 0xDA /* SOS */) {
// end of the datastream
parser._skipBytes(Infinity);
parser.push(null);
return;
}
if (length <= 0) {
// e.g. empty comment
getJpegSize(parser);
return;
}
if (length >= 5 &&
(0xC0 <= code && code <= 0xCF) &&
code !== 0xC4 && code !== 0xC8 && code !== 0xCC) {
parser._bytes(length, function (data) {
parser._skipBytes(Infinity);
parser.push({
width: data.readUInt16BE(3),
height: data.readUInt16BE(1),
type: 'jpg',
mime: 'image/jpeg',
wUnits: 'px',
hUnits: 'px'
});
parser.push(null);
});
return;
}
parser._skipBytes(length, function () {
getJpegSize(parser);
});
});
}
module.exports = function () {
var parser = new ParserStream();
parser._bytes(2, function (data) {
if (data[0] !== 0xFF || data[1] !== 0xD8) {
// first marker of the file MUST be 0xFFD8
parser._skipBytes(Infinity);
parser.push(null);
return;
}
getJpegSize(parser);
});
return parser;
};

View File

@ -0,0 +1,44 @@
'use strict';
var ParserStream = require('../common').ParserStream;
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var SIG_PNG = str2arr('\x89PNG\r\n\x1a\n');
var SIG_IHDR = str2arr('IHDR');
module.exports = function () {
var parser = new ParserStream();
parser._bytes(24, function (data) {
parser._skipBytes(Infinity);
// check PNG signature
if (!sliceEq(data, 0, SIG_PNG)) {
parser.push(null);
return;
}
// check that first chunk is IHDR
if (!sliceEq(data, 12, SIG_IHDR)) {
parser.push(null);
return;
}
parser.push({
width: data.readUInt32BE(16),
height: data.readUInt32BE(20),
type: 'png',
mime: 'image/png',
wUnits: 'px',
hUnits: 'px'
});
parser.push(null);
});
return parser;
};

View File

@ -0,0 +1,40 @@
'use strict';
var ParserStream = require('../common').ParserStream;
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var SIG_8BPS = str2arr('8BPS\x00\x01');
module.exports = function () {
var parser = new ParserStream();
parser._bytes(6, function (data) {
// signature + version
if (!sliceEq(data, 0, SIG_8BPS)) {
parser._skipBytes(Infinity);
parser.push(null);
return;
}
parser._bytes(16, function (data) {
parser._skipBytes(Infinity);
parser.push({
width: data.readUInt32BE(12),
height: data.readUInt32BE(8),
type: 'psd',
mime: 'image/vnd.adobe.photoshop',
wUnits: 'px',
hUnits: 'px'
});
parser.push(null);
});
});
return parser;
};

View File

@ -0,0 +1,188 @@
'use strict';
/* eslint-disable consistent-return */
var Transform = require('stream').Transform;
var STATE_IDENTIFY = 0; // look for '<'
var STATE_PARSE = 1; // extract width and height from svg tag
var STATE_IGNORE = 2; // we got all the data we want, skip the rest
// max size for pre-svg-tag comments plus svg tag itself
var MAX_DATA_LENGTH = 65536;
var SVG_HEADER_RE = /<svg\s[^>]+>/;
var SVG_WIDTH_RE = /[^-]\bwidth="([^%]+?)"|[^-]\bwidth='([^%]+?)'/;
var SVG_HEIGHT_RE = /\bheight="([^%]+?)"|\bheight='([^%]+?)'/;
var SVG_VIEWBOX_RE = /\bview[bB]ox="(.+?)"|\bview[bB]ox='(.+?)'/;
var SVG_UNITS_RE = /in$|mm$|cm$|pt$|pc$|px$|em$|ex$/;
function isWhiteSpace(chr) {
return chr === 0x20 || chr === 0x09 || chr === 0x0D || chr === 0x0A;
}
// Filter NaN, Infinity, < 0
function isFinitePositive(val) {
return typeof val === 'number' && isFinite(val) && val > 0;
}
function svgAttrs(str) {
var width = str.match(SVG_WIDTH_RE);
var height = str.match(SVG_HEIGHT_RE);
var viewbox = str.match(SVG_VIEWBOX_RE);
return {
width: width && (width[1] || width[2]),
height: height && (height[1] || height[2]),
viewbox: viewbox && (viewbox[1] || viewbox[2])
};
}
function units(str) {
if (!SVG_UNITS_RE.test(str)) return 'px';
return str.match(SVG_UNITS_RE)[0];
}
function parseSvg(str) {
if (!SVG_HEADER_RE.test(str)) return;
var attrs = svgAttrs(str.match(SVG_HEADER_RE)[0]);
var width = parseFloat(attrs.width);
var height = parseFloat(attrs.height);
// Extract from direct values
if (attrs.width && attrs.height) {
if (!isFinitePositive(width) || !isFinitePositive(height)) return;
return {
width: width,
height: height,
type: 'svg',
mime: 'image/svg+xml',
wUnits: units(attrs.width),
hUnits: units(attrs.height)
};
}
// Extract from viewbox
var parts = (attrs.viewbox || '').split(' ');
var viewbox = {
width: parts[2],
height: parts[3]
};
var vbWidth = parseFloat(viewbox.width);
var vbHeight = parseFloat(viewbox.height);
if (!isFinitePositive(vbWidth) || !isFinitePositive(vbHeight)) return;
if (units(viewbox.width) !== units(viewbox.height)) return;
var ratio = vbWidth / vbHeight;
if (attrs.width) {
if (!isFinitePositive(width)) return;
return {
width: width,
height: width / ratio,
type: 'svg',
mime: 'image/svg+xml',
wUnits: units(attrs.width),
hUnits: units(attrs.width)
};
}
if (attrs.height) {
if (!isFinitePositive(height)) return;
return {
width: height * ratio,
height: height,
type: 'svg',
mime: 'image/svg+xml',
wUnits: units(attrs.height),
hUnits: units(attrs.height)
};
}
return {
width: vbWidth,
height: vbHeight,
type: 'svg',
mime: 'image/svg+xml',
wUnits: units(viewbox.width),
hUnits: units(viewbox.height)
};
}
module.exports = function () {
var state = STATE_IDENTIFY;
var data_len = 0;
var str = '';
var parser = new Transform({
readableObjectMode: true,
transform: function transform(chunk, encoding, next) {
switch (state) {
case STATE_IDENTIFY:
var i = 0, max = chunk.length;
while (i < max && isWhiteSpace(chunk[i])) i++;
if (i >= max) {
data_len += chunk.length;
if (data_len > MAX_DATA_LENGTH) {
state = STATE_IGNORE;
parser.push(null);
}
} else if (chunk[i] === 0x3c /* < */) {
state = STATE_PARSE;
return transform(chunk, encoding, next);
} else {
state = STATE_IGNORE;
parser.push(null);
}
break;
case STATE_PARSE:
str += chunk.toString();
var result = parseSvg(str);
if (result) {
parser.push(result);
parser.push(null);
break;
}
data_len += chunk.length;
if (data_len > MAX_DATA_LENGTH) {
state = STATE_IGNORE;
parser.push(null);
}
break;
}
next();
},
flush: function () {
state = STATE_IGNORE;
parser.push(null);
}
});
return parser;
};

View File

@ -0,0 +1,112 @@
'use strict';
var ParserStream = require('../common').ParserStream;
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var SIG_1 = str2arr('II\x2A\0');
var SIG_2 = str2arr('MM\0\x2A');
function readUInt16(buffer, offset, is_big_endian) {
return is_big_endian ? buffer.readUInt16BE(offset) : buffer.readUInt16LE(offset);
}
function readUInt32(buffer, offset, is_big_endian) {
return is_big_endian ? buffer.readUInt32BE(offset) : buffer.readUInt32LE(offset);
}
function readIFDValue(data, data_offset, is_big_endian) {
var type = readUInt16(data, data_offset + 2, is_big_endian);
var values = readUInt32(data, data_offset + 4, is_big_endian);
if (values !== 1 || (type !== 3 && type !== 4)) {
return null;
}
if (type === 3) {
return readUInt16(data, data_offset + 8, is_big_endian);
}
return readUInt32(data, data_offset + 8, is_big_endian);
}
module.exports = function () {
var parser = new ParserStream();
// read header
parser._bytes(8, function (data) {
// check TIFF signature
if (!sliceEq(data, 0, SIG_1) && !sliceEq(data, 0, SIG_2)) {
parser._skipBytes(Infinity);
parser.push(null);
return;
}
var is_big_endian = (data[0] === 77 /* 'MM' */);
var count = readUInt32(data, 4, is_big_endian) - 8;
if (count < 0) {
parser._skipBytes(Infinity);
parser.push(null);
return;
}
function safeSkip(parser, count, callback) {
if (count === 0) { // parser._skipBytes throws error if count === 0
callback();
return;
}
parser._skipBytes(count, callback);
}
// skip until IFD
safeSkip(parser, count, function () {
// read number of IFD entries
parser._bytes(2, function (data) {
var ifd_size = readUInt16(data, 0, is_big_endian) * 12;
if (ifd_size <= 0) {
parser._skipBytes(Infinity);
parser.push(null);
return;
}
// read all IFD entries
parser._bytes(ifd_size, function (data) {
parser._skipBytes(Infinity);
var i, width, height, tag;
for (i = 0; i < ifd_size; i += 12) {
tag = readUInt16(data, i, is_big_endian);
if (tag === 256) {
width = readIFDValue(data, i, is_big_endian);
} else if (tag === 257) {
height = readIFDValue(data, i, is_big_endian);
}
}
if (width && height) {
parser.push({
width: width,
height: height,
type: 'tiff',
mime: 'image/tiff',
wUnits: 'px',
hUnits: 'px'
});
}
parser.push(null);
});
});
});
});
return parser;
};

View File

@ -0,0 +1,104 @@
'use strict';
/* eslint-disable no-bitwise */
var ParserStream = require('../common').ParserStream;
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var SIG_RIFF = str2arr('RIFF');
var SIG_WEBPVP8 = str2arr('WEBPVP8');
function parseVP8(parser) {
parser._bytes(14, function (data) {
parser._skipBytes(Infinity);
if (data[7] !== 0x9D || data[8] !== 0x01 || data[9] !== 0x2A) {
// bad code block signature
parser.push(null);
return;
}
parser.push({
width: data.readUInt16LE(10) & 0x3FFF,
height: data.readUInt16LE(12) & 0x3FFF,
type: 'webp',
mime: 'image/webp',
wUnits: 'px',
hUnits: 'px'
});
parser.push(null);
});
}
function parseVP8L(parser) {
parser._bytes(9, function (data) {
parser._skipBytes(Infinity);
if (data[4] !== 0x2F) {
// bad code block signature
parser.push(null);
return;
}
var bits = data.readUInt32LE(5);
parser.push({
width: (bits & 0x3FFF) + 1,
height: ((bits >> 14) & 0x3FFF) + 1,
type: 'webp',
mime: 'image/webp',
wUnits: 'px',
hUnits: 'px'
});
parser.push(null);
});
}
function parseVP8X(parser) {
parser._bytes(14, function (data) {
parser._skipBytes(Infinity);
parser.push({
// TODO: replace with `data.readUIntLE(8, 3) + 1`
// when 0.10 support is dropped
width: ((data[10] << 16) | (data[9] << 8) | data[8]) + 1,
height: ((data[13] << 16) | (data[12] << 8) | data[11]) + 1,
type: 'webp',
mime: 'image/webp',
wUnits: 'px',
hUnits: 'px'
});
parser.push(null);
});
}
module.exports = function () {
var parser = new ParserStream();
parser._bytes(16, function (data) {
// check /^RIFF....WEBPVP8([ LX])$/ signature
if (sliceEq(data, 0, SIG_RIFF) && sliceEq(data, 8, SIG_WEBPVP8)) {
switch (data[15]) {
case 32/*' '*/: parseVP8(parser); return;
case 76/* L */: parseVP8L(parser); return;
case 88/* X */: parseVP8X(parser); return;
}
} else {
parser._skipBytes(Infinity);
parser.push(null);
}
});
return parser;
};

View File

@ -0,0 +1,25 @@
'use strict';
/* eslint-disable consistent-return */
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var readUInt16LE = require('../common').readUInt16LE;
var SIG_BM = str2arr('BM');
module.exports = function (data) {
if (data.length < 26) return;
if (!sliceEq(data, 0, SIG_BM)) return;
return {
width: readUInt16LE(data, 18),
height: readUInt16LE(data, 22),
type: 'bmp',
mime: 'image/bmp',
wUnits: 'px',
hUnits: 'px'
};
};

View File

@ -0,0 +1,27 @@
'use strict';
/* eslint-disable consistent-return */
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var readUInt16LE = require('../common').readUInt16LE;
var SIG_GIF87a = str2arr('GIF87a');
var SIG_GIF89a = str2arr('GIF89a');
module.exports = function (data) {
if (data.length < 10) return;
if (!sliceEq(data, 0, SIG_GIF87a) && !sliceEq(data, 0, SIG_GIF89a)) return;
return {
width: readUInt16LE(data, 6),
height: readUInt16LE(data, 8),
type: 'gif',
mime: 'image/gif',
wUnits: 'px',
hUnits: 'px'
};
};

View File

@ -0,0 +1,65 @@
'use strict';
/* eslint-disable consistent-return */
var readUInt16BE = require('../common').readUInt16BE;
module.exports = function (data) {
if (data.length < 2) return;
// first marker of the file MUST be 0xFFD8
if (data[0] !== 0xFF || data[1] !== 0xD8) return;
var offset = 2;
for (;;) {
if (data.length - offset < 2) return;
// not a JPEG marker
if (data[offset++] !== 0xFF) return;
var code = data[offset++];
var length;
// skip padding bytes
while (code === 0xFF) code = data[offset++];
// standalone markers, according to JPEG 1992,
// http://www.w3.org/Graphics/JPEG/itu-t81.pdf, see Table B.1
if ((0xD0 <= code && code <= 0xD9) || code === 0x01) {
length = 0;
} else if (0xC0 <= code && code <= 0xFE) {
// the rest of the unreserved markers
if (data.length - offset < 2) return;
length = readUInt16BE(data, offset) - 2;
offset += 2;
} else {
// unknown markers
return;
}
if (code === 0xD9 /* EOI */ || code === 0xDA /* SOS */) {
// end of the datastream
return;
}
if (length >= 5 &&
(0xC0 <= code && code <= 0xCF) &&
code !== 0xC4 && code !== 0xC8 && code !== 0xCC) {
if (data.length - offset < length) return;
return {
width: readUInt16BE(data, offset + 3),
height: readUInt16BE(data, offset + 1),
type: 'jpg',
mime: 'image/jpeg',
wUnits: 'px',
hUnits: 'px'
};
}
offset += length;
}
};

View File

@ -0,0 +1,31 @@
'use strict';
/* eslint-disable consistent-return */
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var readUInt32BE = require('../common').readUInt32BE;
var SIG_PNG = str2arr('\x89PNG\r\n\x1a\n');
var SIG_IHDR = str2arr('IHDR');
module.exports = function (data) {
if (data.length < 24) return;
// check PNG signature
if (!sliceEq(data, 0, SIG_PNG)) return;
// check that first chunk is IHDR
if (!sliceEq(data, 12, SIG_IHDR)) return;
return {
width: readUInt32BE(data, 16),
height: readUInt32BE(data, 20),
type: 'png',
mime: 'image/png',
wUnits: 'px',
hUnits: 'px'
};
};

View File

@ -0,0 +1,27 @@
'use strict';
/* eslint-disable consistent-return */
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var readUInt32BE = require('../common').readUInt32BE;
var SIG_8BPS = str2arr('8BPS\x00\x01');
module.exports = function (data) {
if (data.length < 6 + 16) return;
// signature + version
if (!sliceEq(data, 0, SIG_8BPS)) return;
return {
width: readUInt32BE(data, 6 + 12),
height: readUInt32BE(data, 6 + 8),
type: 'psd',
mime: 'image/vnd.adobe.photoshop',
wUnits: 'px',
hUnits: 'px'
};
};

View File

@ -0,0 +1,131 @@
'use strict';
/* eslint-disable consistent-return */
function isWhiteSpace(chr) {
return chr === 0x20 || chr === 0x09 || chr === 0x0D || chr === 0x0A;
}
// Filter NaN, Infinity, < 0
function isFinitePositive(val) {
return typeof val === 'number' && isFinite(val) && val > 0;
}
function canBeSvg(buf) {
var i = 0, max = buf.length;
while (i < max && isWhiteSpace(buf[i])) i++;
if (i === max) return false;
return buf[i] === 0x3c; /* < */
}
var SVG_HEADER_RE = /<svg\s[^>]+>/;
var SVG_WIDTH_RE = /[^-]\bwidth="([^%]+?)"|[^-]\bwidth='([^%]+?)'/;
var SVG_HEIGHT_RE = /\bheight="([^%]+?)"|\bheight='([^%]+?)'/;
var SVG_VIEWBOX_RE = /\bview[bB]ox="(.+?)"|\bview[bB]ox='(.+?)'/;
var SVG_UNITS_RE = /in$|mm$|cm$|pt$|pc$|px$|em$|ex$/;
function svgAttrs(str) {
var width = str.match(SVG_WIDTH_RE);
var height = str.match(SVG_HEIGHT_RE);
var viewbox = str.match(SVG_VIEWBOX_RE);
return {
width: width && (width[1] || width[2]),
height: height && (height[1] || height[2]),
viewbox: viewbox && (viewbox[1] || viewbox[2])
};
}
function units(str) {
if (!SVG_UNITS_RE.test(str)) return 'px';
return str.match(SVG_UNITS_RE)[0];
}
module.exports = function (data) {
if (!canBeSvg(data)) return;
var str = '';
for (var i = 0; i < data.length; i++) {
// 1. We can't rely on buffer features
// 2. Don't care about UTF16 because ascii is enougth for our goals
str += String.fromCharCode(data[i]);
}
if (!SVG_HEADER_RE.test(str)) return;
var attrs = svgAttrs(str.match(SVG_HEADER_RE)[0]);
var width = parseFloat(attrs.width);
var height = parseFloat(attrs.height);
// Extract from direct values
if (attrs.width && attrs.height) {
if (!isFinitePositive(width) || !isFinitePositive(height)) return;
return {
width: width,
height: height,
type: 'svg',
mime: 'image/svg+xml',
wUnits: units(attrs.width),
hUnits: units(attrs.height)
};
}
// Extract from viewbox
var parts = (attrs.viewbox || '').split(' ');
var viewbox = {
width: parts[2],
height: parts[3]
};
var vbWidth = parseFloat(viewbox.width);
var vbHeight = parseFloat(viewbox.height);
if (!isFinitePositive(vbWidth) || !isFinitePositive(vbHeight)) return;
if (units(viewbox.width) !== units(viewbox.height)) return;
var ratio = vbWidth / vbHeight;
if (attrs.width) {
if (!isFinitePositive(width)) return;
return {
width: width,
height: width / ratio,
type: 'svg',
mime: 'image/svg+xml',
wUnits: units(attrs.width),
hUnits: units(attrs.width)
};
}
if (attrs.height) {
if (!isFinitePositive(height)) return;
return {
width: height * ratio,
height: height,
type: 'svg',
mime: 'image/svg+xml',
wUnits: units(attrs.height),
hUnits: units(attrs.height)
};
}
return {
width: vbWidth,
height: vbHeight,
type: 'svg',
mime: 'image/svg+xml',
wUnits: units(viewbox.width),
hUnits: units(viewbox.height)
};
};

View File

@ -0,0 +1,86 @@
'use strict';
/* eslint-disable consistent-return */
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var readUInt16LE = require('../common').readUInt16LE;
var readUInt16BE = require('../common').readUInt16BE;
var readUInt32LE = require('../common').readUInt32LE;
var readUInt32BE = require('../common').readUInt32BE;
var SIG_1 = str2arr('II\x2A\0');
var SIG_2 = str2arr('MM\0\x2A');
function readUInt16(buffer, offset, is_big_endian) {
return is_big_endian ? readUInt16BE(buffer, offset) : readUInt16LE(buffer, offset);
}
function readUInt32(buffer, offset, is_big_endian) {
return is_big_endian ? readUInt32BE(buffer, offset) : readUInt32LE(buffer, offset);
}
function readIFDValue(data, data_offset, is_big_endian) {
var type = readUInt16(data, data_offset + 2, is_big_endian);
var values = readUInt32(data, data_offset + 4, is_big_endian);
if (values !== 1 || (type !== 3 && type !== 4)) return null;
if (type === 3) {
return readUInt16(data, data_offset + 8, is_big_endian);
}
return readUInt32(data, data_offset + 8, is_big_endian);
}
module.exports = function (data) {
if (data.length < 8) return;
// check TIFF signature
if (!sliceEq(data, 0, SIG_1) && !sliceEq(data, 0, SIG_2)) return;
var is_big_endian = (data[0] === 77 /* 'MM' */);
var count = readUInt32(data, 4, is_big_endian) - 8;
if (count < 0) return;
// skip until IFD
var offset = count + 8;
if (data.length - offset < 2) return;
// read number of IFD entries
var ifd_size = readUInt16(data, offset + 0, is_big_endian) * 12;
if (ifd_size <= 0) return;
offset += 2;
// read all IFD entries
if (data.length - offset < ifd_size) return;
var i, width, height, tag;
for (i = 0; i < ifd_size; i += 12) {
tag = readUInt16(data, offset + i, is_big_endian);
if (tag === 256) {
width = readIFDValue(data, offset + i, is_big_endian);
} else if (tag === 257) {
height = readIFDValue(data, offset + i, is_big_endian);
}
}
if (width && height) {
return {
width: width,
height: height,
type: 'tiff',
mime: 'image/tiff',
wUnits: 'px',
hUnits: 'px'
};
}
};

View File

@ -0,0 +1,80 @@
'use strict';
/* eslint-disable no-bitwise */
/* eslint-disable consistent-return */
var str2arr = require('../common').str2arr;
var sliceEq = require('../common').sliceEq;
var readUInt16LE = require('../common').readUInt16LE;
var readUInt32LE = require('../common').readUInt32LE;
var SIG_RIFF = str2arr('RIFF');
var SIG_WEBPVP8 = str2arr('WEBPVP8');
function parseVP8(data) {
if (data.length < 16 + 14) return;
if (data[16 + 7] !== 0x9D || data[16 + 8] !== 0x01 || data[16 + 9] !== 0x2A) {
// bad code block signature
return;
}
return {
width: readUInt16LE(data, 16 + 10) & 0x3FFF,
height: readUInt16LE(data, 16 + 12) & 0x3FFF,
type: 'webp',
mime: 'image/webp',
wUnits: 'px',
hUnits: 'px'
};
}
function parseVP8L(data) {
if (data.length < 16 + 9) return;
if (data[16 + 4] !== 0x2F) return;
var bits = readUInt32LE(data, 16 + 5);
return {
width: (bits & 0x3FFF) + 1,
height: ((bits >> 14) & 0x3FFF) + 1,
type: 'webp',
mime: 'image/webp',
wUnits: 'px',
hUnits: 'px'
};
}
function parseVP8X(data) {
if (data.length < 16 + 14) return;
return {
// TODO: replace with `data.readUIntLE(8, 3) + 1`
// when 0.10 support is dropped
width: ((data[16 + 10] << 16) | (data[16 + 9] << 8) | data[16 + 8]) + 1,
height: ((data[16 + 13] << 16) | (data[16 + 12] << 8) | data[16 + 11]) + 1,
type: 'webp',
mime: 'image/webp',
wUnits: 'px',
hUnits: 'px'
};
}
module.exports = function (data) {
if (data.length < 16) return;
// check /^RIFF....WEBPVP8([ LX])$/ signature
if (sliceEq(data, 0, SIG_RIFF) && sliceEq(data, 8, SIG_WEBPVP8)) {
switch (data[15]) {
case 32/*' '*/: return parseVP8(data);
case 76/* L */: return parseVP8L(data);
case 88/* X */: return parseVP8X(data);
}
}
};

View File

@ -0,0 +1,13 @@
'use strict';
module.exports = {
bmp: require('./parse_stream/bmp'),
gif: require('./parse_stream/gif'),
jpeg: require('./parse_stream/jpeg'),
png: require('./parse_stream/png'),
psd: require('./parse_stream/psd'),
svg: require('./parse_stream/svg'),
tiff: require('./parse_stream/tiff'),
webp: require('./parse_stream/webp')
};

View File

@ -0,0 +1,13 @@
'use strict';
module.exports = {
bmp: require('./parse_sync/bmp'),
gif: require('./parse_sync/gif'),
jpeg: require('./parse_sync/jpeg'),
png: require('./parse_sync/png'),
psd: require('./parse_sync/psd'),
svg: require('./parse_sync/svg'),
tiff: require('./parse_sync/tiff'),
webp: require('./parse_sync/webp')
};

View File

@ -0,0 +1,82 @@
{
"_args": [
[
"probe-image-size@5.0.0",
"/home/shihaam/www/freezer.shihaam.me/app"
]
],
"_from": "probe-image-size@5.0.0",
"_id": "probe-image-size@5.0.0",
"_inBundle": false,
"_integrity": "sha512-V6uBYw5eBc5UVIE7MUZD6Nxg0RYuGDWLDenEn0B1WC6PcTvn1xdQ6HLDDuznefsiExC6rNrCz7mFRBo0f3Xekg==",
"_location": "/probe-image-size",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "probe-image-size@5.0.0",
"name": "probe-image-size",
"escapedName": "probe-image-size",
"rawSpec": "5.0.0",
"saveSpec": null,
"fetchSpec": "5.0.0"
},
"_requiredBy": [
"/metaflac-js2"
],
"_resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-5.0.0.tgz",
"_spec": "5.0.0",
"_where": "/home/shihaam/www/freezer.shihaam.me/app",
"bugs": {
"url": "https://github.com/nodeca/probe-image-size/issues"
},
"dependencies": {
"deepmerge": "^4.0.0",
"inherits": "^2.0.3",
"next-tick": "^1.0.0",
"request": "^2.83.0",
"stream-parser": "~0.3.1"
},
"description": "Get image size without full download (JPG, GIF, PNG, WebP, BMP, TIFF, PSD)",
"devDependencies": {
"coveralls": "^3.0.0",
"eslint": "^6.0.1",
"from2": "^2.1",
"istanbul": "^0.4.1",
"mocha": "^6.1.4"
},
"files": [
"index.js",
"http.js",
"stream.js",
"sync.js",
"lib/"
],
"homepage": "https://github.com/nodeca/probe-image-size#readme",
"keywords": [
"image",
"size",
"jpg",
"jpeg",
"gif",
"png",
"webp",
"tiff",
"bmp",
"svg",
"psd"
],
"license": "MIT",
"name": "probe-image-size",
"repository": {
"type": "git",
"url": "git+https://github.com/nodeca/probe-image-size.git"
},
"scripts": {
"coverage": "rm -rf coverage && ./node_modules/.bin/istanbul cover node_modules/.bin/_mocha",
"lint": "eslint .",
"report-coveralls": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage",
"test": "npm run lint && ./node_modules/.bin/mocha"
},
"version": "5.0.0"
}

56
buildfiles/app/node_modules/probe-image-size/stream.js generated vendored Normal file
View File

@ -0,0 +1,56 @@
'use strict';
var ProbeError = require('./lib/common').ProbeError;
var parsers = require('./lib/parsers_stream');
var PassThrough = require('stream').PassThrough;
module.exports = function probeStream(stream) {
var proxy = new PassThrough();
var cnt = 0; // count of working parsers
var result = new Promise(function (resolve, reject) {
stream.on('error', reject);
proxy.on('error', reject);
function nope() {}
function parserEnd() {
proxy.unpipe(this);
this.removeAllListeners();
cnt--;
// if all parsers finished without success -> fail.
if (!cnt) reject(new ProbeError('unrecognized file format', 'ECONTENT'));
}
Object.keys(parsers).forEach(function (type) {
var pStream = parsers[type]();
cnt++;
pStream.once('data', resolve);
pStream.once('end', parserEnd);
// silently ignore errors because user does not need to know
// that something wrong is happening here
pStream.on('error', nope);
proxy.pipe(pStream);
});
});
function cleanup() {
// request stream doesn't have unpipe, https://github.com/request/request/issues/874
if (typeof stream.unpipe === 'function') stream.unpipe(proxy);
proxy.end();
}
result.then(cleanup).catch(cleanup);
stream.pipe(proxy);
return result;
};
module.exports.parsers = parsers;

28
buildfiles/app/node_modules/probe-image-size/sync.js generated vendored Normal file
View File

@ -0,0 +1,28 @@
'use strict';
var parsers = require('./lib/parsers_sync');
function probeBuffer(buffer) {
var parser_names = Object.keys(parsers);
for (var i = 0; i < parser_names.length; i++) {
var result = parsers[parser_names[i]](buffer);
if (result) return result;
}
return null;
}
///////////////////////////////////////////////////////////////////////
// Exports
//
module.exports = function get_image_size(src) {
return probeBuffer(src);
};
module.exports.parsers = parsers;