@@ -8,88 +8,129 @@ module.exports = function (gm) {
88
99 var proto = gm . prototype ;
1010
11+ /**
12+ * `identify` states
13+ */
14+
15+ const IDENTIFYING = 1 ;
16+ const IDENTIFIED = 2 ;
17+
18+ /**
19+ * Map getter functions to output names.
20+ *
21+ * - format: specifying the -format argument (see man gm)
22+ * - verbose: use -verbose instead of -format (only if necessary b/c its slow)
23+ * - helper: use the conversion helper
24+ */
25+
1126 var map = {
12- 'size ' : 'size'
13- , 'format ' : ' format'
14- , 'depth ' : 'depth'
15- , 'color ' : 'color'
16- , 'orientation ' : 'Orientation'
17- , 'res ' : 'Resolution'
18- , 'filesize ' : 'Filesize'
27+ 'format ' : { key : 'format' , format : '%m' }
28+ , 'depth ' : { key : 'depth' , format : '%q' }
29+ , 'filesize ' : { key : 'Filesize' , format : '%b' }
30+ , 'size ' : { key : 'size' , format : '%wx%h' , helper : 'Geometry' }
31+ , 'color ' : { key : 'color' , format : '%k' , helper : 'Colors' }
32+ , 'orientation ' : { key : 'Orientation' , verbose : true }
33+ , 'res ' : { key : 'Resolution' , verbose : true }
1934 }
2035
36+ /**
37+ * Getter functions
38+ */
39+
2140 Object . keys ( map ) . forEach ( function ( getter ) {
2241 proto [ getter ] = function ( opts , callback ) {
2342 if ( ! callback ) callback = opts , opts = { } ;
43+ if ( ! callback ) return this ;
2444
25- var key = map [ getter ]
45+ var val = map [ getter ]
46+ , key = val . key
2647 , self = this ;
2748
2849 if ( self . data [ key ] ) {
2950 callback . call ( self , null , self . data [ key ] ) ;
3051 return self ;
3152 }
3253
33- self . identify ( opts , function ( err , stdout , stderr , cmd ) {
34- if ( err ) {
35- return callback . call ( self , err , stdout , stderr , cmd ) ;
54+ self . bufferStream = ! ! opts . bufferStream ;
55+
56+ self . on ( getter , createListener ( callback ) ) ;
57+
58+ if ( val . verbose ) {
59+ self . identify ( opts , function ( err , stdout , stderr , cmd ) {
60+ self . emit ( getter , err , self . data [ key ] , stdout , stderr , cmd ) ;
61+ } ) ;
62+ return self ;
63+ }
64+
65+ var args = makeArgs ( self , val ) ;
66+ self . _exec ( args , function ( err , stdout , stderr , cmd ) {
67+ var result = ( stdout || '' ) . trim ( ) ;
68+
69+ if ( val . helper in helper ) {
70+ helper [ val . helper ] ( self . data , result ) ;
71+ } else {
72+ self . data [ key ] = result ;
3673 }
3774
38- callback . call ( self , null , self . data [ key ] ) ;
75+ self . emit ( getter , err , self . data [ key ] , stdout , stderr , cmd ) ;
3976 } ) ;
4077
4178 return self ;
4279 }
4380 } ) ;
4481
82+ /**
83+ * identify command
84+ *
85+ * Overwrites all internal data with the parsed output
86+ * which is more accurate than the fast shortcut
87+ * getters.
88+ */
89+
4590 proto . identify = function identify ( opts , callback ) {
4691 if ( ! callback ) callback = opts , opts = { } ;
4792 if ( ! callback ) return this ;
4893
4994 var self = this ;
50- self . bufferStream = ! ! opts . bufferStream ;
5195
52- if ( self . _identifying ) {
53- self . _queue . push ( callback ) ;
96+ if ( IDENTIFIED === self . _identifyState ) {
97+ callback . call ( self , null , self . data ) ;
5498 return self ;
5599 }
56100
57- if ( Object . keys ( self . data ) . length ) {
58- callback . call ( self , null , self . data ) ;
101+ self . on ( 'identify' , createListener ( callback ) ) ;
102+
103+ if ( IDENTIFYING === self . _identifyState ) {
59104 return self ;
60105 }
61106
62- self . _queue = [ callback ] ;
63- self . _identifying = true ;
107+ self . _identifyState = IDENTIFYING ;
108+ self . bufferStream = ! ! opts . bufferStream ;
64109
65- var args = [
66- 'identify'
67- , '-ping'
68- , '-verbose'
69- , self . sourceStream ? '-' : self . source
70- ] ;
110+ var args = makeArgs ( self , { verbose : true } ) ;
71111
72112 self . _exec ( args , function ( err , stdout , stderr , cmd ) {
73113 if ( err ) {
74- return callback . call ( self , err , self . data , stdout , stderr , cmd ) ;
114+ self . emit ( 'identify' , err , self . data , stdout , stderr , cmd ) ;
115+ return ;
75116 }
76117
77- // parse response
78- var err = parse ( stdout , self ) ;
118+ err = parse ( stdout , self ) ;
79119
80- var i = self . _queue . length ;
81- while ( i -- ) {
82- self . _queue [ i ] . call ( self , err , self . data ) ;
120+ if ( err ) {
121+ self . emit ( 'identify' , err , self . data , stdout , stderr , cmd ) ;
122+ return ;
83123 }
84124
85- self . _identifying = false ;
125+ self . emit ( 'identify' , null , self . data ) ;
126+ self . _identifyState = IDENTIFIED ;
86127 } ) ;
87128
88129 return self ;
89130 }
90131
91132 /**
92- * Parse Identify response frames
133+ * Parses `identify` responses.
93134 *
94135 * @param {String } stdout
95136 * @param {Gm } self
@@ -162,7 +203,47 @@ module.exports = function (gm) {
162203 }
163204
164205 /**
165- * helpers.
206+ * Create an argument array for the identify command.
207+ *
208+ * @param {gm } self
209+ * @param {Object } val
210+ * @return {Array }
211+ */
212+
213+ function makeArgs ( self , val ) {
214+ var args = [
215+ 'identify'
216+ , '-ping'
217+ ] ;
218+
219+ if ( val . format ) {
220+ args . push ( '-format' , val . format ) ;
221+ }
222+
223+ if ( val . verbose ) {
224+ args . push ( '-verbose' ) ;
225+ }
226+
227+ args . push ( self . sourceStream ? '-' : self . source ) ;
228+ return args ;
229+ }
230+
231+ /**
232+ * Creates a listener function which calls `callback`
233+ * with proper scope and arguments.
234+ *
235+ * @param {Function } callback
236+ * @return {Function }
237+ */
238+
239+ function createListener ( callback ) {
240+ return function ( err , data , stdout , stderr , cmd ) {
241+ return callback . call ( this , err , data , stdout , stderr , cmd ) ;
242+ }
243+ }
244+
245+ /**
246+ * identify -verbose helpers
166247 */
167248
168249 var helper = gm . identifyHelpers = { } ;
0 commit comments