| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 /** | 5 /** |
| 6 * @typedef {{ | 6 * @typedef {{ |
| 7 * cache: (boolean|undefined), | 7 * cache: (boolean|undefined), |
| 8 * priority: (number|undefined), | 8 * priority: (number|undefined), |
| 9 * taskId: number, | 9 * taskId: number, |
| 10 * timestamp: (number|undefined), | 10 * timestamp: (number|undefined), |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 }.bind(this); | 239 }.bind(this); |
| 240 | 240 |
| 241 // Download data urls directly since they are not supported by XmlHttpRequest. | 241 // Download data urls directly since they are not supported by XmlHttpRequest. |
| 242 var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/); | 242 var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/); |
| 243 if (dataUrlMatches) { | 243 if (dataUrlMatches) { |
| 244 this.image_.src = this.request_.url; | 244 this.image_.src = this.request_.url; |
| 245 this.contentType_ = dataUrlMatches[1]; | 245 this.contentType_ = dataUrlMatches[1]; |
| 246 return; | 246 return; |
| 247 } | 247 } |
| 248 | 248 |
| 249 var fileType = FileType.getTypeForName(this.request_.url); |
| 250 |
| 249 // Load RAW images by using Piex loader instead of XHR. | 251 // Load RAW images by using Piex loader instead of XHR. |
| 250 var fileType = FileType.getTypeForName(this.request_.url); | |
| 251 if (fileType.type === 'raw') { | 252 if (fileType.type === 'raw') { |
| 252 var timer = metrics.getTracker().startTiming( | 253 var timer = metrics.getTracker().startTiming( |
| 253 metrics.Categories.INTERNALS, | 254 metrics.Categories.INTERNALS, |
| 254 metrics.timing.Variables.EXTRACT_THUMBNAIL_FROM_RAW, | 255 metrics.timing.Variables.EXTRACT_THUMBNAIL_FROM_RAW, |
| 255 fileType.subtype); | 256 fileType.subtype); |
| 256 this.piexLoader_.load(this.request_.url).then(function(data) { | 257 this.piexLoader_.load(this.request_.url).then(function(data) { |
| 257 timer.send(); | 258 timer.send(); |
| 258 var blob = new Blob([data.thumbnail], {type: 'image/jpeg'}); | 259 var blob = new Blob([data.thumbnail], {type: 'image/jpeg'}); |
| 259 var url = URL.createObjectURL(blob); | 260 var url = URL.createObjectURL(blob); |
| 260 this.image_.src = url; | 261 this.image_.src = url; |
| 261 this.request_.orientation = data.orientation; | 262 this.request_.orientation = data.orientation; |
| 262 this.request_.colorSpace = data.colorSpace; | 263 this.request_.colorSpace = data.colorSpace; |
| 263 }.bind(this), function(error) { | 264 }.bind(this), function(error) { |
| 264 console.error('PiexLoaderError: ', error); | 265 console.error('PiexLoaderError: ', error); |
| 265 onFailure(); | 266 onFailure(); |
| 266 }); | 267 }); |
| 267 return; | 268 return; |
| 268 } | 269 } |
| 269 | 270 |
| 271 // Load video thumbnails by using video tag instead of XHR. |
| 272 if (fileType.type === 'video') { |
| 273 this.createVideoThumbnailUrl_(this.request_.url).then(function(url) { |
| 274 this.image_.src = url; |
| 275 }.bind(this)).catch(function(error) { |
| 276 console.error('Video thumbnail error: ', error); |
| 277 onFailure(); |
| 278 }); |
| 279 return; |
| 280 } |
| 281 |
| 270 // Fetch the image via authorized XHR and parse it. | 282 // Fetch the image via authorized XHR and parse it. |
| 271 var parseImage = function(contentType, blob) { | 283 var parseImage = function(contentType, blob) { |
| 272 if (contentType) | 284 if (contentType) |
| 273 this.contentType_ = contentType; | 285 this.contentType_ = contentType; |
| 274 if (fileType.type === 'video') { | 286 this.image_.src = URL.createObjectURL(blob); |
| 275 this.createThumbnailUrl_(blob).then(function(url) { | |
| 276 this.image_.src = url; | |
| 277 }.bind(this), onFailure); | |
| 278 } else { | |
| 279 this.image_.src = URL.createObjectURL(blob); | |
| 280 } | |
| 281 }.bind(this); | 287 }.bind(this); |
| 282 | 288 |
| 283 // Request raw data via XHR. | 289 // Request raw data via XHR. |
| 284 this.xhr_.load(this.request_.url, parseImage, onFailure); | 290 this.xhr_.load(this.request_.url, parseImage, onFailure); |
| 285 }; | 291 }; |
| 286 | 292 |
| 287 /** | 293 /** |
| 288 * Creates a video thumbnail data url from video file. | 294 * Creates a video thumbnail data url from video file. |
| 289 * | 295 * |
| 290 * @param {!Blob} blob Blob object of video file | 296 * @param {string} url Video URL. |
| 291 * @return {!Promise<!string>} Promise that resolves with the data url of video | 297 * @return {!Promise<Blob>} Promise that resolves with the data url of video |
| 292 * thumbnail. | 298 * thumbnail. |
| 293 * @private | 299 * @private |
| 294 */ | 300 */ |
| 295 ImageRequest.prototype.createThumbnailUrl_ = function(blob) { | 301 ImageRequest.prototype.createVideoThumbnailUrl_ = function(url) { |
| 296 var url = URL.createObjectURL(blob); | |
| 297 var video = document.createElement('video'); | 302 var video = document.createElement('video'); |
| 298 return new Promise(function(resolve, reject) { | 303 return new Promise(function(resolve, reject) { |
| 299 video.addEventListener('canplay', resolve); | 304 video.addEventListener('canplay', resolve); |
| 300 video.addEventListener('error', reject); | 305 video.addEventListener('error', reject); |
| 301 video.currentTime = ImageRequest.VIDEO_THUMBNAIL_POSITION; | 306 video.currentTime = ImageRequest.VIDEO_THUMBNAIL_POSITION; |
| 302 video.preload = 'auto'; | 307 video.preload = 'auto'; |
| 303 video.src = url; | 308 video.src = url; |
| 304 }).then(function() { | 309 }).then(function() { |
| 305 URL.revokeObjectURL(url); | |
| 306 var canvas = document.createElement('canvas'); | 310 var canvas = document.createElement('canvas'); |
| 307 canvas.width = video.videoWidth; | 311 canvas.width = video.videoWidth; |
| 308 canvas.height = video.videoHeight; | 312 canvas.height = video.videoHeight; |
| 309 canvas.getContext('2d').drawImage(video, 0, 0); | 313 canvas.getContext('2d').drawImage(video, 0, 0); |
| 310 return canvas.toDataURL(); | 314 return canvas.toDataURL(); |
| 311 }, function(errev) { | |
| 312 URL.revokeObjectURL(url); | |
| 313 console.error(errev); | |
| 314 return Promise.reject(errev); | |
| 315 }); | 315 }); |
| 316 }; | 316 }; |
| 317 | 317 |
| 318 /** | 318 /** |
| 319 * Creates a XmlHttpRequest wrapper with injected OAuth2 authentication headers. | 319 * Creates a XmlHttpRequest wrapper with injected OAuth2 authentication headers. |
| 320 * @constructor | 320 * @constructor |
| 321 */ | 321 */ |
| 322 function AuthorizedXHR() { | 322 function AuthorizedXHR() { |
| 323 this.xhr_ = null; | 323 this.xhr_ = null; |
| 324 this.aborted_ = false; | 324 this.aborted_ = false; |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' + | 582 this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' + |
| 583 'ABAAEAAAICTAEAOw=='; | 583 'ABAAEAAAICTAEAOw=='; |
| 584 | 584 |
| 585 this.xhr_.onload = function() {}; | 585 this.xhr_.onload = function() {}; |
| 586 this.xhr_.abort(); | 586 this.xhr_.abort(); |
| 587 | 587 |
| 588 // Dispose memory allocated by Canvas. | 588 // Dispose memory allocated by Canvas. |
| 589 this.canvas_.width = 0; | 589 this.canvas_.width = 0; |
| 590 this.canvas_.height = 0; | 590 this.canvas_.height = 0; |
| 591 }; | 591 }; |
| OLD | NEW |