UNPKG

2.95 kBJavaScriptView Raw
1'use strict';
2
3var fs = require('fs');
4var path = require('path');
5
6var detector = require('./detector');
7
8var handlers = {};
9var types = require('./types');
10
11// load all available handlers
12types.forEach(function (type) {
13 handlers[type] = require('./types/' + type);
14});
15
16// Maximum buffer size, with a default of 128 kilobytes.
17// TO-DO: make this adaptive based on the initial signature of the image
18var MaxBufferSize = 128*1024;
19
20function lookup (buffer, filepath) {
21 // detect the file type.. don't rely on the extension
22 var type = detector(buffer, filepath);
23
24 // find an appropriate handler for this file type
25 if (type in handlers) {
26 var size = handlers[type].calculate(buffer, filepath);
27 if (size !== false) {
28 size.type = type;
29 return size;
30 }
31 }
32
33 // throw up, if we don't understand the file
34 throw new TypeError('unsupported file type: ' + type + ' (file: ' + filepath + ')');
35}
36
37function asyncFileToBuffer (filepath, callback) {
38 // open the file in read only mode
39 fs.open(filepath, 'r', function (err, descriptor) {
40 if (err) { return callback(err); }
41 var size = fs.fstatSync(descriptor).size;
42 if (size <= 0){return callback(new Error("File size is not greater than 0 —— " + filepath)); }
43 var bufferSize = Math.min(size, MaxBufferSize);
44 var buffer = new Buffer(bufferSize);
45 // read first buffer block from the file, asynchronously
46 fs.read(descriptor, buffer, 0, bufferSize, 0, function (err) {
47 if (err) { return callback(err); }
48 // close the file, we are done
49 fs.close(descriptor, function (err) {
50 callback(err, buffer);
51 });
52 });
53 });
54}
55
56function syncFileToBuffer (filepath) {
57 // read from the file, synchronously
58 var descriptor = fs.openSync(filepath, 'r');
59 var size = fs.fstatSync(descriptor).size;
60 var bufferSize = Math.min(size, MaxBufferSize);
61 var buffer = new Buffer(bufferSize);
62 fs.readSync(descriptor, buffer, 0, bufferSize, 0);
63 fs.closeSync(descriptor);
64 return buffer;
65}
66
67/**
68 * @params input - buffer or relative/absolute path of the image file
69 * @params callback - optional function for async detection
70 */
71module.exports = function (input, callback) {
72
73 // Handle buffer input
74 if (Buffer.isBuffer(input)) {
75 return lookup(input);
76 }
77
78 // input should be a string at this point
79 if (typeof input !== 'string') {
80 throw new TypeError('invalid invocation');
81 }
82
83 // resolve the file path
84 var filepath = path.resolve(input);
85
86 if (typeof callback === 'function') {
87 asyncFileToBuffer(filepath, function (err, buffer) {
88 if (err) { return callback(err); }
89
90 // return the dimensions
91 var dimensions;
92 try {
93 dimensions = lookup(buffer, filepath);
94 } catch (e) {
95 err = e;
96 }
97 callback(err, dimensions);
98 });
99 } else {
100 var buffer = syncFileToBuffer(filepath);
101 return lookup(buffer, filepath);
102 }
103};
104
105module.exports.types = types;