new identify parser

properly handles nested output
more getter tests

closes #20
master
Aaron Heckmann 13 years ago
parent 710ee0fd2d
commit 3304511c1b
  1. 1
      .gitignore
  2. BIN
      examples/imgs/photo.JPG
  3. 2
      index.js
  4. 211
      lib/getters.js
  5. 15
      test/getterColor.js
  6. 9
      test/getterDepth.js
  7. 8
      test/getterFilesize.js
  8. 11
      test/getterFormat.js
  9. 25
      test/getterIdentify.js
  10. 8
      test/getterRes.js
  11. 12
      test/getterSize.js

1
.gitignore vendored

@ -4,5 +4,6 @@ examples/imgs/*
!examples/imgs/original.png
!examples/imgs/original.gif
!examples/imgs/morpher.jpg
!examples/imgs/photo.JPG
*.swp
*.swo

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

@ -57,7 +57,7 @@ function gm (source, height, color) {
* Augment the prototype.
*/
require("./lib/getters")(gm.prototype);
require("./lib/getters")(gm);
require("./lib/args")(gm.prototype);
require("./lib/drawing")(gm.prototype);
require("./lib/convenience")(gm.prototype);

@ -5,123 +5,156 @@
* Extend proto.
*/
module.exports = function (proto) {
module.exports = function (gm) {
;['size', 'format', 'depth', 'color', 'res', 'filesize'].forEach(function (getter) {
var proto = gm.prototype;
proto[getter] = function (opts, callback) {
if (!callback) callback = opts, opts = {};
var self = this;
if (self.data[getter]) {
callback.call(self, null, self.data[getter]);
return self;
}
;['size', 'format', 'depth', 'color', 'res', 'filesize'].forEach(function (getter) {
proto[getter] = function (opts, callback) {
if (!callback) callback = opts, opts = {};
self.identify(opts, function (err, stdout, stderr, cmd) {
if (err) {
return callback.call(self, err, stdout, stderr, cmd);
var self = this;
if (self.data[getter]) {
callback.call(self, null, self.data[getter]);
return self;
}
callback.call(self, null, self.data[getter]);
});
self.identify(opts, function (err, stdout, stderr, cmd) {
if (err) {
return callback.call(self, err, stdout, stderr, cmd);
}
return self;
}
});
callback.call(self, null, self.data[getter]);
});
proto.identify = function identify (opts, callback) {
if (!callback) callback = opts, opts = {};
var self = this;
if (!callback) return self;
self.bufferStream = !! opts.bufferStream;
return self;
}
});
if (self._identifying) {
self._iq.push(callback);
return self;
}
proto.identify = function identify (opts, callback) {
if (!callback) callback = opts, opts = {};
if (Object.keys(self.data).length) {
callback.call(self, null, self.data);
return self;
}
var self = this;
self._iq = [callback];
self._identifying = true;
if (!callback) return self;
var args = ['identify', '-ping', '-verbose', self.sourceStream ? '-' : self.source];
self.bufferStream = !! opts.bufferStream;
self._exec("gm", args, function (err, stdout, stderr) {
if (err) {
return callback.call(self, err, stdout, stderr, cmd);
if (self._identifying) {
self._iq.push(callback);
return self;
}
stdout = (stdout||"").trim().replace(/\r\n|\r/g, "\n");
if (Object.keys(self.data).length) {
callback.call(self, null, self.data);
return self;
}
var parts = stdout.split("\n")
, len = parts.length
, rgx = /^( *)(.*)/
, data = self.data
, result
, keyval
, i = 0;
self._iq = [callback];
self._identifying = true;
var handle = {};
var args = ['identify', '-ping', '-verbose', self.sourceStream ? '-' : self.source];
handle.Geometry = function Geometry (val) {
var split = val.split("x");
data.size = {
width: parseInt(split[0], 10)
, height: parseInt(split[1], 10)
self._exec("gm", args, function (err, stdout, stderr) {
if (err) {
return callback.call(self, err, stdout, stderr, cmd);
}
};
handle.Format = function Format (val) {
data.format = val.split(" ")[0];
};
stdout = (stdout||"").trim().replace(/\r\n|\r/g, "\n");
var parts = stdout.split("\n");
// skip the first line (its just the filename)
parts.shift();
var len = parts.length
, rgx = /^( *)([^:]+): *(.*)$/
, out = { indent: {} }
, level = null
, lastkey
, i = 0
, res
, o
for (; i < len; ++i) {
res = rgx.exec(parts[i]);
if (!res) continue
var indent = res[1].length
, key = res[2] ? res[2].trim() : ''
, val = res[3] ? res[3].trim() : null
// first iteration?
if (!level) {
level = indent
o = out.root = out.indent[level] = self.data;
} else if (indent < level) {
// outdent
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;
}
handle.Depth = function Depth (val) {
data.depth = parseInt(val, 10);
};
var idx = self._iq.length;
handle.Colors = function Colors (val) {
data.color = parseInt(val, 10);
};
while (idx--) {
self._iq[idx].call(self, null, self.data);
}
handle.Resolution = function Resolution (val) {
data.res = val;
};
self._identifying = false;
});
handle.Filesize = function Filesize (val) {
data.filesize = val;
};
return self;
}
for (; i < len; ++i) {
result = rgx.exec(parts[i]);
if (!result) continue;
if (2 !== result[1].length) continue;
/**
* helpers.
*/
var keyval = result[2].split(":");
if (keyval.length <= 1) continue;
var helper = gm.identifyHelpers = {};
if (keyval[0] in handle) {
handle[keyval[0]](keyval[1].trim());
} else {
data[keyval[0]] = keyval[1].trim();
}
helper.Geometry = function Geometry (o, val) {
var split = val.split("x");
o.size = {
width: parseInt(split[0], 10)
, height: parseInt(split[1], 10)
}
};
var idx = self._iq.length;
helper.Format = function Format (o, val) {
o.format = val.split(" ")[0];
};
while (idx--) {
self._iq[idx].call(self, null, self.data);
}
helper.Depth = function Depth (o, val) {
o.depth = parseInt(val, 10);
};
self._identifying = false;
});
helper.Colors = function Colors (o, val) {
o.color = parseInt(val, 10);
};
helper.Resolution = function Resolution (o, val) {
o.res = val;
};
helper.Filesize = function Filesize (o, val) {
o.filesize = val;
};
return self;
}}
}

@ -1,10 +1,17 @@
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
module.exports = function (gm, dir, finish) {
var assert = require('assert')
module.exports = function (_, dir, finish, gm) {
gm(dir + '/blue.gif').color(function (err, color) {
if (err) return finish(err);
assert.equal(2, color)
assert.equal(this.data.Colors['0'], '( 0, 0,255)\t blue');
assert.equal(this.data.Colors['1'], '( 0, 0, 0)\t black');
finish();
gm
.color(function gettercolor (err) {
finish(err);
});
}

@ -1,10 +1,15 @@
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var assert = require('assert')
module.exports = function (gm, dir, finish) {
gm
.depth(function getterdepth (err) {
finish(err);
.depth(function getterdepth (err, depth) {
if (err) return finish(err);
assert.equal(8, depth);
assert.equal('8 bits-per-pixel component', this.data.Depth);
finish();
});
}

@ -1,10 +1,14 @@
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var assert = require('assert')
module.exports = function (gm, dir, finish) {
gm
.filesize(function getterfilesize (err) {
finish(err);
.filesize(function getterfilesize (err, size) {
if (err) return finish(err);
assert.ok(size === this.data.Filesize, this.data.filesize)
finish();
});
}

@ -1,10 +1,17 @@
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var assert = require('assert');
module.exports = function (gm, dir, finish) {
gm
.format(function getterformat (err) {
finish(err);
.format(function getterformat (err, format) {
if (err) return finish(err);
assert.equal(format, 'JPEG');
assert.equal(this.data.Format, 'JPEG (Joint Photographic Experts Group JFIF format)');
finish();
});
}

@ -1,10 +1,27 @@
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
module.exports = function (gm, dir, finish) {
var assert = require('assert')
gm
.identify(function getteridentify (err) {
finish(err);
module.exports = function (_, dir, finish, gm) {
gm(dir + '/photo.JPG').identify(function (err) {
if (err) return finish(err);
console.error(this.data);
var d = this.data;
assert.equal(d.Orientation, 'TopLeft');
assert.equal(d['JPEG-Quality'], 96);
assert.equal(d['Channel Statistics'].Red['Standard Deviation'], '71.70 (0.2812)');
var ex = d['Profile-EXIF'];
assert.equal(ex.Make, 'Apple');
assert.equal(ex.Model, 'iPad 2');
assert.equal(ex['GPS Info'], 558);
assert.equal(ex['GPS Longitude'], '80/1,4970/100,0/1');
assert.equal(ex['GPS Time Stamp'], '15/1,23/1,945/1');
finish();
});
}

@ -1,10 +1,14 @@
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var assert = require('assert')
module.exports = function (gm, dir, finish) {
gm
.res(function getterres (err) {
finish(err);
.res(function getterres (err, res) {
if (err) return finish(err);
assert.ok(res === this.data.Resolution, this.data.res)
finish();
});
}

@ -1,10 +1,18 @@
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var assert = require('assert');
module.exports = function (gm, dir, finish) {
gm
.size(function gettersize (err) {
finish(err);
.size(function gettersize (err, size) {
if (err) return finish(err);
assert.equal(size.width, 460);
assert.equal(size.height, 155);
assert.equal(this.data.Geometry, '460x155');
finish();
});
}

Loading…
Cancel
Save