/*! * Stylus - plugin - url * Copyright(c) 2010 LearnBoost * MIT Licensed */ /** * Module dependencies. */ var utils = require('../utils') , nodes = require('../nodes') , fs = require('fs'); /** * 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'); }; /** * 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 * * @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'; return type; }; /** * Return image dimensions `[width, height]`. * * @return {Array} * @api private */ Image.prototype.size = function(){ var width , height , type = this.type(); 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': throw new Error('image-size() jpeg support not yet implemented'); break; case 'png': var 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': var 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; } 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]; };