Fully end to end encrypted anonymous chat program. Server only stores public key lookup for users and the encrypted messages. No credentials are transfered to the server, but kept in local browser storage. This allows 100% safe chatting.
https://safechat.ch
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
3.7 KiB
162 lines
3.7 KiB
|
|
|
|
/*! |
|
* 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]; |
|
};
|
|
|