diff options
| author | ruki <waruqi@gmail.com> | 2018-11-08 00:38:48 +0800 |
|---|---|---|
| committer | ruki <waruqi@gmail.com> | 2018-11-07 21:53:09 +0800 |
| commit | 26105034da4fcce7ac883c899d781f016559310d (patch) | |
| tree | c459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/stylus/lib/functions/image.js | |
| parent | 2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff) | |
| download | xmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip | |
switch to vuepress
Diffstat (limited to 'node_modules/stylus/lib/functions/image.js')
| -rw-r--r-- | node_modules/stylus/lib/functions/image.js | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/node_modules/stylus/lib/functions/image.js b/node_modules/stylus/lib/functions/image.js new file mode 100644 index 00000000..5a2c186c --- /dev/null +++ b/node_modules/stylus/lib/functions/image.js @@ -0,0 +1,162 @@ + + +/*! + * Stylus - plugin - url + * Copyright (c) Automattic <developer.wordpress.com> + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils') + , nodes = require('../nodes') + , fs = require('fs') + , path = require('path') + , sax = require('sax'); + +/** + * Initialize a new `Image` with the given `ctx` and `path. + * + * @param {Evaluator} ctx + * @param {String} path + * @api private + */ + +var Image = module.exports = function Image(ctx, path) { + this.ctx = ctx; + this.path = utils.lookup(path, ctx.paths); + if (!this.path) throw new Error('failed to locate file ' + path); +}; + +/** + * Open the image for reading. + * + * @api private + */ + +Image.prototype.open = function(){ + this.fd = fs.openSync(this.path, 'r'); + this.length = fs.fstatSync(this.fd).size; + this.extname = path.extname(this.path).slice(1); +}; + +/** + * Close the file. + * + * @api private + */ + +Image.prototype.close = function(){ + if (this.fd) fs.closeSync(this.fd); +}; + +/** + * Return the type of image, supports: + * + * - gif + * - png + * - jpeg + * - svg + * + * @return {String} + * @api private + */ + +Image.prototype.type = function(){ + var type + , buf = new Buffer(4); + + fs.readSync(this.fd, buf, 0, 4, 0); + + // GIF + if (0x47 == buf[0] && 0x49 == buf[1] && 0x46 == buf[2]) type = 'gif'; + + // PNG + else if (0x50 == buf[1] && 0x4E == buf[2] && 0x47 == buf[3]) type = 'png'; + + // JPEG + else if (0xff == buf[0] && 0xd8 == buf[1]) type = 'jpeg'; + + // SVG + else if ('svg' == this.extname) type = this.extname; + + return type; +}; + +/** + * Return image dimensions `[width, height]`. + * + * @return {Array} + * @api private + */ + +Image.prototype.size = function(){ + var type = this.type() + , width + , height + , buf + , offset + , blockSize + , parser; + + function uint16(b) { return b[1] << 8 | b[0]; } + function uint32(b) { return b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]; } + + // Determine dimensions + switch (type) { + case 'jpeg': + buf = new Buffer(this.length); + fs.readSync(this.fd, buf, 0, this.length, 0); + offset = 4; + blockSize = buf[offset] << 8 | buf[offset + 1]; + + while (offset < this.length) { + offset += blockSize; + if (offset >= this.length || 0xff != buf[offset]) break; + // SOF0 or SOF2 (progressive) + if (0xc0 == buf[offset + 1] || 0xc2 == buf[offset + 1]) { + height = buf[offset + 5] << 8 | buf[offset + 6]; + width = buf[offset + 7] << 8 | buf[offset + 8]; + } else { + offset += 2; + blockSize = buf[offset] << 8 | buf[offset + 1]; + } + } + break; + case 'png': + buf = new Buffer(8); + // IHDR chunk width / height uint32_t big-endian + fs.readSync(this.fd, buf, 0, 8, 16); + width = uint32(buf); + height = uint32(buf.slice(4, 8)); + break; + case 'gif': + buf = new Buffer(4); + // width / height uint16_t little-endian + fs.readSync(this.fd, buf, 0, 4, 6); + width = uint16(buf); + height = uint16(buf.slice(2, 4)); + break; + case 'svg': + offset = Math.min(this.length, 1024); + buf = new Buffer(offset); + fs.readSync(this.fd, buf, 0, offset, 0); + buf = buf.toString('utf8'); + parser = sax.parser(true); + parser.onopentag = function(node) { + if ('svg' == node.name && node.attributes.width && node.attributes.height) { + width = parseInt(node.attributes.width, 10); + height = parseInt(node.attributes.height, 10); + } + }; + parser.write(buf).close(); + break; + } + + if ('number' != typeof width) throw new Error('failed to find width of "' + this.path + '"'); + if ('number' != typeof height) throw new Error('failed to find height of "' + this.path + '"'); + + return [width, height]; +}; |
