| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 | 
							- /**
 
-  * Extend proto.
 
-  */
 
- module.exports = function (gm) {
 
-   var proto = gm.prototype;
 
-   /**
 
-    * `identify` states
 
-    */
 
-   const IDENTIFYING = 1;
 
-   const IDENTIFIED = 2;
 
-   /**
 
-    * Map getter functions to output names.
 
-    *
 
-    * - format: specifying the -format argument (see man gm)
 
-    * - verbose: use -verbose instead of -format (only if necessary b/c its slow)
 
-    * - helper: use the conversion helper
 
-    */
 
-   var map = {
 
-       'format': { key: 'format', format: '%m ', helper: 'Format' }
 
-     , 'depth':  { key: 'depth',  format: '%q' }
 
-     , 'filesize': { key: 'Filesize', format: '%b' }
 
-     , 'size':  { key: 'size', format: '%wx%h ', helper: 'Geometry' }
 
-     , 'color': { key: 'color', format: '%k',  helper: 'Colors' }
 
-     , 'orientation': { key: 'Orientation', verbose: true }
 
-     , 'res':   { key: 'Resolution', verbose: true }
 
-   }
 
-   /**
 
-    * Getter functions
 
-    */
 
-   Object.keys(map).forEach(function (getter) {
 
-     proto[getter] = function (opts, callback) {
 
-       if (!callback) callback = opts, opts = {};
 
-       if (!callback) return this;
 
-       var val = map[getter]
 
-         , key = val.key
 
-         , self = this;
 
-       if (self.data[key]) {
 
-         callback.call(self, null, self.data[key]);
 
-         return self;
 
-       }
 
-       self.on(getter, callback);
 
-       self.bufferStream = !!opts.bufferStream;
 
-       if (val.verbose) {
 
-         self.identify(opts, function (err, stdout, stderr, cmd) {
 
-           if (err) {
 
-             self.emit(getter, err, self.data[key], stdout, stderr, cmd);
 
-           } else {
 
-             self.emit(getter, err, self.data[key]);
 
-           }
 
-         });
 
-         return self;
 
-       }
 
-       var args = makeArgs(self, val);
 
-       self._exec(args, function (err, stdout, stderr, cmd) {
 
-         if (err) {
 
-           self.emit(getter, err, self.data[key], stdout, stderr, cmd);
 
-           return;
 
-         }
 
-         var result = (stdout||'').trim();
 
-         if (val.helper in helper) {
 
-           helper[val.helper](self.data, result);
 
-         } else {
 
-           self.data[key] = result;
 
-         }
 
-         self.emit(getter, err, self.data[key]);
 
-       });
 
-       return self;
 
-     }
 
-   });
 
-   /**
 
-    * identify command
 
-    *
 
-    * Overwrites all internal data with the parsed output
 
-    * which is more accurate than the fast shortcut
 
-    * getters.
 
-    */
 
-   proto.identify = function identify (opts, callback) {
 
-     // identify with pattern
 
-     if (typeof(opts) === 'string') {
 
-       opts = {
 
-         format: opts
 
-       }
 
-     }
 
-     if (!callback) callback = opts, opts = {};
 
-     if (!callback) return this;
 
-     if (opts && opts.format) return identifyPattern.call(this, opts, callback);
 
-     var self = this;
 
-     if (IDENTIFIED === self._identifyState) {
 
-       callback.call(self, null, self.data);
 
-       return self;
 
-     }
 
-     self.on('identify', callback);
 
-     if (IDENTIFYING === self._identifyState) {
 
-       return self;
 
-     }
 
-     self._identifyState = IDENTIFYING;
 
-     self.bufferStream = !!opts.bufferStream;
 
-     var args = makeArgs(self, { verbose: true });
 
-     self._exec(args, function (err, stdout, stderr, cmd) {
 
-       if (err) {
 
-         self.emit('identify', err, self.data, stdout, stderr, cmd);
 
-         return;
 
-       }
 
-       err = parse(stdout, self);
 
-       if (err) {
 
-         self.emit('identify', err, self.data, stdout, stderr, cmd);
 
-         return;
 
-       }
 
-       self.data.path = self.source;
 
-       self.emit('identify', null, self.data);
 
-       self._identifyState = IDENTIFIED;
 
-     });
 
-     return self;
 
-   }
 
-   /**
 
-    * identify with pattern
 
-    *
 
-    * Execute `identify -format` with custom pattern
 
-    */
 
-   function identifyPattern (opts, callback) {
 
-     var self = this;
 
-     self.bufferStream = !!opts.bufferStream;
 
-     var args = makeArgs(self, opts);
 
-     self._exec(args, function (err, stdout, stderr, cmd) {
 
-       if (err) {
 
-         return callback.call(self, err, undefined, stdout, stderr, cmd);
 
-       }
 
-       callback.call(self, err, (stdout||'').trim());
 
-     });
 
-     return self;
 
-   }
 
-   /**
 
-    * Parses `identify` responses.
 
-    *
 
-    * @param {String} stdout
 
-    * @param {Gm} self
 
-    * @return {Error} [optionally]
 
-    */
 
-   function parse (stdout, self) {
 
-     // normalize
 
-     var parts = (stdout||"").trim().replace(/\r\n|\r/g, "\n").split("\n");
 
-     // skip the first line (its just the filename)
 
-     parts.shift();
 
-     try {
 
-       var len = parts.length
 
-         , rgx1 = /^( *)(.+?): (.*)$/ // key: val
 
-         , rgx2 = /^( *)(.+?):$/      // key: begin nested object
 
-         , out = { indent: {} }
 
-         , level = null
 
-         , lastkey
 
-         , i = 0
 
-         , res
 
-         , o
 
-       for (; i < len; ++i) {
 
-         res = rgx1.exec(parts[i]) || rgx2.exec(parts[i]);
 
-         if (!res) continue;
 
-         var indent = res[1].length
 
-           , key = res[2] ? res[2].trim() : '';
 
-         if ('Image' == key) continue;
 
-         var val = res[3] ? res[3].trim() : null;
 
-         // first iteration?
 
-         if (null === level) {
 
-           level = indent;
 
-           o = out.root = out.indent[level] = self.data;
 
-         } else if (indent < level) {
 
-           // outdent
 
-           if (!(indent in out.indent)) {
 
-             continue;
 
-           }
 
-           o = out.indent[indent];
 
-         } else if (indent > level) {
 
-           // dropping into a nested object
 
-           out.indent[level] = o;
 
-           // wierd format, key/val pair with nested children. discard the val
 
-           o = o[lastkey] = {};
 
-         }
 
-         level = indent;
 
-         if (val) {
 
-           o[key] = val;
 
-           if (key in helper) {
 
-             helper[key](o, val);
 
-           }
 
-         }
 
-         lastkey = key;
 
-       }
 
-     } catch (err) {
 
-       err.message = err.message + "\n\n  Identify stdout:\n  " + stdout;
 
-       return err;
 
-     }
 
-   }
 
-   /**
 
-    * Create an argument array for the identify command.
 
-    *
 
-    * @param {gm} self
 
-    * @param {Object} val
 
-    * @return {Array}
 
-    */
 
-   function makeArgs (self, val) {
 
-     var args = [
 
-         'identify'
 
-       , '-ping'
 
-     ];
 
-     if (val.format) {
 
-       args.push('-format', val.format);
 
-     }
 
-     if (val.verbose) {
 
-       args.push('-verbose');
 
-     }
 
-     args = args.concat(self.src());
 
-     return args;
 
-   }
 
-   /**
 
-    * identify -verbose helpers
 
-    */
 
-   var helper = gm.identifyHelpers = {};
 
-   helper.Geometry = function Geometry (o, val) {
 
-     // We only want the size of the first frame.
 
-     // Each frame is separated by a space.
 
-     var split = val.split(" ").shift().split("x");
 
-     o.size = {
 
-         width:  parseInt(split[0], 10)
 
-       , height: parseInt(split[1], 10)
 
-     }
 
-   };
 
-   helper.Format = function Format (o, val) {
 
-     o.format = val.split(" ")[0];
 
-   };
 
-   helper.Depth = function Depth (o, val) {
 
-     o.depth = parseInt(val, 10);
 
-   };
 
-   helper.Colors = function Colors (o, val) {
 
-     o.color = parseInt(val, 10);
 
-   };
 
- }
 
 
  |