Blame view

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