OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 importScripts('function_sequence.js'); | 5 importScripts('function_sequence.js'); |
6 importScripts('function_parallel.js'); | 6 importScripts('function_parallel.js'); |
7 | 7 |
8 function Id3Parser(parent) { | 8 function Id3Parser(parent) { |
9 MetadataParser.call(this, parent, 'id3', /\.(mp3)$/i); | 9 MetadataParser.call(this, parent, 'id3', /\.(mp3)$/i); |
10 } | 10 } |
11 | 11 |
12 Id3Parser.prototype = {__proto__: MetadataParser.prototype}; | 12 Id3Parser.prototype = {__proto__: MetadataParser.prototype}; |
13 | 13 |
14 /** | 14 /** |
15 * Reads synchsafe integer. | 15 * Reads synchsafe integer. |
16 * 'SynchSafe' term is taken from id3 documentation. | 16 * 'SynchSafe' term is taken from id3 documentation. |
17 * | 17 * |
18 * @private | |
19 * @param {ByteReader} reader - reader to use. | 18 * @param {ByteReader} reader - reader to use. |
20 * @param {int} length - bytes to read. | 19 * @param {int} length - bytes to read. |
21 * @return {int} //TODO(JSDOC). | 20 * @return {int} //TODO(JSDOC). |
| 21 * @private |
22 */ | 22 */ |
23 Id3Parser.readSynchSafe_ = function(reader, length) { | 23 Id3Parser.readSynchSafe_ = function(reader, length) { |
24 var rv = 0; | 24 var rv = 0; |
25 | 25 |
26 switch (length) { | 26 switch (length) { |
27 case 4: | 27 case 4: |
28 rv = reader.readScalar(1, false) << 21; | 28 rv = reader.readScalar(1, false) << 21; |
29 case 3: | 29 case 3: |
30 rv |= reader.readScalar(1, false) << 14; | 30 rv |= reader.readScalar(1, false) << 14; |
31 case 2: | 31 case 2: |
32 rv |= reader.readScalar(1, false) << 7; | 32 rv |= reader.readScalar(1, false) << 7; |
33 case 1: | 33 case 1: |
34 rv |= reader.readScalar(1, false); | 34 rv |= reader.readScalar(1, false); |
35 } | 35 } |
36 | 36 |
37 return rv; | 37 return rv; |
38 }; | 38 }; |
39 | 39 |
40 /** | 40 /** |
41 * Reads 3bytes integer. | 41 * Reads 3bytes integer. |
42 * | 42 * |
43 * @private | |
44 * @param {ByteReader} reader - reader to use. | 43 * @param {ByteReader} reader - reader to use. |
45 * @return {int} //TODO(JSDOC). | 44 * @return {int} //TODO(JSDOC). |
46 * @return {int} | 45 * @private |
47 */ | 46 */ |
48 Id3Parser.readUInt24_ = function(reader) { | 47 Id3Parser.readUInt24_ = function(reader) { |
49 return reader.readScalar(2, false) << 16 | reader.readScalar(1, false); | 48 return reader.readScalar(2, false) << 16 | reader.readScalar(1, false); |
50 }; | 49 }; |
51 | 50 |
52 /** | 51 /** |
53 * Reads string from reader with specified encoding | 52 * Reads string from reader with specified encoding |
54 * | 53 * |
55 * @private | |
56 * @param {ByteReader} reader reader to use. | 54 * @param {ByteReader} reader reader to use. |
57 * @param {int} encoding string encoding. | 55 * @param {int} encoding string encoding. |
58 * @param {int} size maximum string size. Actual result may be shorter. | 56 * @param {int} size maximum string size. Actual result may be shorter. |
59 * @return {string} // TODO(JSDOC). | 57 * @return {string} // TODO(JSDOC). |
| 58 * @private |
60 */ | 59 */ |
61 Id3Parser.prototype.readString_ = function(reader, encoding, size) { | 60 Id3Parser.prototype.readString_ = function(reader, encoding, size) { |
62 switch (encoding) { | 61 switch (encoding) { |
63 case Id3Parser.v2.ENCODING.ISO_8859_1: | 62 case Id3Parser.v2.ENCODING.ISO_8859_1: |
64 return reader.readNullTerminatedString(size); | 63 return reader.readNullTerminatedString(size); |
65 | 64 |
66 case Id3Parser.v2.ENCODING.UTF_16: | 65 case Id3Parser.v2.ENCODING.UTF_16: |
67 return reader.readNullTerminatedStringUTF16(true, size); | 66 return reader.readNullTerminatedStringUTF16(true, size); |
68 | 67 |
69 case Id3Parser.v2.ENCODING.UTF_16BE: | 68 case Id3Parser.v2.ENCODING.UTF_16BE: |
70 return reader.readNullTerminatedStringUTF16(false, size); | 69 return reader.readNullTerminatedStringUTF16(false, size); |
71 | 70 |
72 case Id3Parser.v2.ENCODING.UTF_8: | 71 case Id3Parser.v2.ENCODING.UTF_8: |
73 // TODO: implement UTF_8. | 72 // TODO: implement UTF_8. |
74 this.log('UTF8 encoding not supported, used ISO_8859_1 instead'); | 73 this.log('UTF8 encoding not supported, used ISO_8859_1 instead'); |
75 return reader.readNullTerminatedString(size); | 74 return reader.readNullTerminatedString(size); |
76 | 75 |
77 default: { | 76 default: { |
78 this.log('Unsupported encoding in ID3 tag: ' + encoding); | 77 this.log('Unsupported encoding in ID3 tag: ' + encoding); |
79 return ''; | 78 return ''; |
80 } | 79 } |
81 } | 80 } |
82 }; | 81 }; |
83 | 82 |
84 /** | 83 /** |
85 * Reads text frame from reader. | 84 * Reads text frame from reader. |
86 * | 85 * |
87 * @private | |
88 * @param {ByteReader} reader reader to use. | 86 * @param {ByteReader} reader reader to use. |
89 * @param {int} majorVersion major id3 version to use. | 87 * @param {int} majorVersion major id3 version to use. |
90 * @param {Object} frame frame so store data at. | 88 * @param {Object} frame frame so store data at. |
91 * @param {int} end frame end position in reader. | 89 * @param {int} end frame end position in reader. |
| 90 * @private |
92 */ | 91 */ |
93 Id3Parser.prototype.readTextFrame_ = function(reader, | 92 Id3Parser.prototype.readTextFrame_ = function(reader, |
94 majorVersion, | 93 majorVersion, |
95 frame, | 94 frame, |
96 end) { | 95 end) { |
97 frame.encoding = reader.readScalar(1, false, end); | 96 frame.encoding = reader.readScalar(1, false, end); |
98 frame.value = this.readString_(reader, frame.encoding, end - reader.tell()); | 97 frame.value = this.readString_(reader, frame.encoding, end - reader.tell()); |
99 }; | 98 }; |
100 | 99 |
101 /** | 100 /** |
102 * Reads user defined text frame from reader. | 101 * Reads user defined text frame from reader. |
103 * | 102 * |
104 * @private | |
105 * @param {ByteReader} reader reader to use. | 103 * @param {ByteReader} reader reader to use. |
106 * @param {int} majorVersion major id3 version to use. | 104 * @param {int} majorVersion major id3 version to use. |
107 * @param {Object} frame frame so store data at. | 105 * @param {Object} frame frame so store data at. |
108 * @param {int} end frame end position in reader. | 106 * @param {int} end frame end position in reader. |
| 107 * @private |
109 */ | 108 */ |
110 Id3Parser.prototype.readUserDefinedTextFrame_ = function(reader, | 109 Id3Parser.prototype.readUserDefinedTextFrame_ = function(reader, |
111 majorVersion, | 110 majorVersion, |
112 frame, | 111 frame, |
113 end) { | 112 end) { |
114 frame.encoding = reader.readScalar(1, false, end); | 113 frame.encoding = reader.readScalar(1, false, end); |
115 | 114 |
116 frame.description = this.readString_( | 115 frame.description = this.readString_( |
117 reader, | 116 reader, |
118 frame.encoding, | 117 frame.encoding, |
119 end - reader.tell()); | 118 end - reader.tell()); |
120 | 119 |
121 frame.value = this.readString_( | 120 frame.value = this.readString_( |
122 reader, | 121 reader, |
123 frame.encoding, | 122 frame.encoding, |
124 end - reader.tell()); | 123 end - reader.tell()); |
125 }; | 124 }; |
126 | 125 |
127 /** | 126 /** |
128 * @private | |
129 * @param {ByteReader} reader Reader to use. | 127 * @param {ByteReader} reader Reader to use. |
130 * @param {number} majorVersion Major id3 version to use. | 128 * @param {number} majorVersion Major id3 version to use. |
131 * @param {Object} frame Frame so store data at. | 129 * @param {Object} frame Frame so store data at. |
132 * @param {number} end Frame end position in reader. | 130 * @param {number} end Frame end position in reader. |
| 131 * @private |
133 */ | 132 */ |
134 Id3Parser.prototype.readPIC_ = function(reader, majorVersion, frame, end) { | 133 Id3Parser.prototype.readPIC_ = function(reader, majorVersion, frame, end) { |
135 frame.encoding = reader.readScalar(1, false, end); | 134 frame.encoding = reader.readScalar(1, false, end); |
136 frame.format = reader.readNullTerminatedString(3, end - reader.tell()); | 135 frame.format = reader.readNullTerminatedString(3, end - reader.tell()); |
137 frame.pictureType = reader.readScalar(1, false, end); | 136 frame.pictureType = reader.readScalar(1, false, end); |
138 frame.description = this.readString_(reader, | 137 frame.description = this.readString_(reader, |
139 frame.encoding, | 138 frame.encoding, |
140 end - reader.tell()); | 139 end - reader.tell()); |
141 | 140 |
142 | 141 |
143 if (frame.format == '-->') { | 142 if (frame.format == '-->') { |
144 frame.imageUrl = reader.readNullTerminatedString(end - reader.tell()); | 143 frame.imageUrl = reader.readNullTerminatedString(end - reader.tell()); |
145 } else { | 144 } else { |
146 frame.imageUrl = reader.readImage(end - reader.tell()); | 145 frame.imageUrl = reader.readImage(end - reader.tell()); |
147 } | 146 } |
148 }; | 147 }; |
149 | 148 |
150 /** | 149 /** |
151 * @private | |
152 * @param {ByteReader} reader Reader to use. | 150 * @param {ByteReader} reader Reader to use. |
153 * @param {number} majorVersion Major id3 version to use. | 151 * @param {number} majorVersion Major id3 version to use. |
154 * @param {Object} frame Frame so store data at. | 152 * @param {Object} frame Frame so store data at. |
155 * @param {number} end Frame end position in reader. | 153 * @param {number} end Frame end position in reader. |
| 154 * @private |
156 */ | 155 */ |
157 Id3Parser.prototype.readAPIC_ = function(reader, majorVersion, frame, end) { | 156 Id3Parser.prototype.readAPIC_ = function(reader, majorVersion, frame, end) { |
158 this.vlog('Extracting picture'); | 157 this.vlog('Extracting picture'); |
159 frame.encoding = reader.readScalar(1, false, end); | 158 frame.encoding = reader.readScalar(1, false, end); |
160 frame.mime = reader.readNullTerminatedString(end - reader.tell()); | 159 frame.mime = reader.readNullTerminatedString(end - reader.tell()); |
161 frame.pictureType = reader.readScalar(1, false, end); | 160 frame.pictureType = reader.readScalar(1, false, end); |
162 frame.description = this.readString_( | 161 frame.description = this.readString_( |
163 reader, | 162 reader, |
164 frame.encoding, | 163 frame.encoding, |
165 end - reader.tell()); | 164 end - reader.tell()); |
166 | 165 |
167 if (frame.mime == '-->') { | 166 if (frame.mime == '-->') { |
168 frame.imageUrl = reader.readNullTerminatedString(end - reader.tell()); | 167 frame.imageUrl = reader.readNullTerminatedString(end - reader.tell()); |
169 } else { | 168 } else { |
170 frame.imageUrl = reader.readImage(end - reader.tell()); | 169 frame.imageUrl = reader.readImage(end - reader.tell()); |
171 } | 170 } |
172 }; | 171 }; |
173 | 172 |
174 /** | 173 /** |
175 * Reads string from reader with specified encoding | 174 * Reads string from reader with specified encoding |
176 * | 175 * |
177 * @private | |
178 * @param {ByteReader} reader reader to use. | 176 * @param {ByteReader} reader reader to use. |
179 * @param {number} majorVersion //TODO(JSDOC). | 177 * @param {number} majorVersion //TODO(JSDOC). |
180 * @return {Object} frame read. | 178 * @return {Object} frame read. |
| 179 * @private |
181 */ | 180 */ |
182 Id3Parser.prototype.readFrame_ = function(reader, majorVersion) { | 181 Id3Parser.prototype.readFrame_ = function(reader, majorVersion) { |
183 if (reader.eof()) | 182 if (reader.eof()) |
184 return null; | 183 return null; |
185 | 184 |
186 var frame = {}; | 185 var frame = {}; |
187 | 186 |
188 reader.pushSeek(reader.tell(), ByteReader.SEEK_BEG); | 187 reader.pushSeek(reader.tell(), ByteReader.SEEK_BEG); |
189 | 188 |
190 var position = reader.tell(); | 189 var position = reader.tell(); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 'id3v2parser', | 303 'id3v2parser', |
305 [ | 304 [ |
306 function readHead(file) { | 305 function readHead(file) { |
307 util.readFileBytes(file, 0, 10, this.nextStep, this.onError, | 306 util.readFileBytes(file, 0, 10, this.nextStep, this.onError, |
308 this); | 307 this); |
309 }, | 308 }, |
310 | 309 |
311 /** | 310 /** |
312 * Check if passed array of 10 bytes contains ID3 header. | 311 * Check if passed array of 10 bytes contains ID3 header. |
313 * @param {File} file File to check and continue reading if ID3 | 312 * @param {File} file File to check and continue reading if ID3 |
314 * metadata found | 313 * metadata found. |
315 * @param {ByteReader} reader Reader to fill with stream bytes. | 314 * @param {ByteReader} reader Reader to fill with stream bytes. |
316 */ | 315 */ |
317 function checkId3v2(file, reader) { | 316 function checkId3v2(file, reader) { |
318 if (reader.readString(3) == 'ID3') { | 317 if (reader.readString(3) == 'ID3') { |
319 this.logger.vlog('id3v2 found'); | 318 this.logger.vlog('id3v2 found'); |
320 var id3v2 = metadata.id3v2 = {}; | 319 var id3v2 = metadata.id3v2 = {}; |
321 id3v2.major = reader.readScalar(1, false); | 320 id3v2.major = reader.readScalar(1, false); |
322 id3v2.minor = reader.readScalar(1, false); | 321 id3v2.minor = reader.readScalar(1, false); |
323 id3v2.flags = reader.readScalar(1, false); | 322 id3v2.flags = reader.readScalar(1, false); |
324 id3v2.size = Id3Parser.readSynchSafe_(reader, 4); | 323 id3v2.size = Id3Parser.readSynchSafe_(reader, 4); |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 TYER: 'ID3_YEAR', | 697 TYER: 'ID3_YEAR', |
699 WCOP: 'ID3_COPYRIGHT', | 698 WCOP: 'ID3_COPYRIGHT', |
700 WOAF: 'ID3_OFFICIAL_AUDIO_FILE_WEBPAGE', | 699 WOAF: 'ID3_OFFICIAL_AUDIO_FILE_WEBPAGE', |
701 WOAR: 'ID3_OFFICIAL_ARTIST', | 700 WOAR: 'ID3_OFFICIAL_ARTIST', |
702 WOAS: 'ID3_OFFICIAL_AUDIO_SOURCE_WEBPAGE', | 701 WOAS: 'ID3_OFFICIAL_AUDIO_SOURCE_WEBPAGE', |
703 WPUB: 'ID3_PUBLISHERS_OFFICIAL_WEBPAGE' | 702 WPUB: 'ID3_PUBLISHERS_OFFICIAL_WEBPAGE' |
704 } | 703 } |
705 }; | 704 }; |
706 | 705 |
707 MetadataDispatcher.registerParserClass(Id3Parser); | 706 MetadataDispatcher.registerParserClass(Id3Parser); |
OLD | NEW |