From bebe1a4e81eeb6a52bf55572568475421fad88fe Mon Sep 17 00:00:00 2001 From: Michael Klaus Date: Fri, 15 Mar 2013 01:01:28 +0100 Subject: [PATCH] returning error on IE9 instead of issuing bad http request --- .../jquery-fileupload/vendor/load-image.js | 137 ++++++++++++++++-- 1 file changed, 122 insertions(+), 15 deletions(-) diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js b/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js index 96a149e..b5ee0da 100644 --- a/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js +++ b/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js @@ -1,15 +1,18 @@ /* - * JavaScript Load Image 1.2.1 + * JavaScript Load Image 1.3 * https://github.com/blueimp/JavaScript-Load-Image * * Copyright 2011, Sebastian Tschan * https://blueimp.net * + * iOS image scaling fixes based on + * https://github.com/stomita/ios-imagefile-megapixel + * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT */ -/*jslint nomen: true */ +/*jslint nomen: true, bitwise: true */ /*global window, document, URL, webkitURL, Blob, File, FileReader, define */ (function ($) { @@ -34,15 +37,22 @@ // (Firefox 3.6) support the File API but not Blobs: (window.File && file instanceof File)) { url = oUrl = loadImage.createObjectURL(file); + // Store the file type for resize processing: + img._type = file.type; } else { - url = file; + callback({"type": "error"}); // this led to a broken image request in IE9: url = file; } if (url) { img.src = url; return img; } - return loadImage.readFile(file, function (url) { - img.src = url; + return loadImage.readFile(file, function (e) { + var target = e.target; + if (target && target.result) { + img.src = target.result; + } else { + callback(e); + } }); }, // The check for URL.revokeObjectURL fixes an issue with Opera 12, @@ -51,6 +61,99 @@ (window.URL && URL.revokeObjectURL && URL) || (window.webkitURL && webkitURL); + // Detects subsampling in JPEG images: + loadImage.detectSubsampling = function (img) { + var iw = img.width, + ih = img.height, + canvas, + ctx; + if (iw * ih > 1024 * 1024) { // only consider mexapixel images + canvas = document.createElement('canvas'); + canvas.width = canvas.height = 1; + ctx = canvas.getContext('2d'); + ctx.drawImage(img, -iw + 1, 0); + // subsampled image becomes half smaller in rendering size. + // check alpha channel value to confirm image is covering edge pixel or not. + // if alpha value is 0 image is not covering, hence subsampled. + return ctx.getImageData(0, 0, 1, 1).data[3] === 0; + } + return false; + }; + + // Detects vertical squash in JPEG images: + loadImage.detectVerticalSquash = function (img, ih) { + var canvas = document.createElement('canvas'), + ctx = canvas.getContext('2d'), + data, + sy, + ey, + py, + alpha; + canvas.width = 1; + canvas.height = ih; + ctx.drawImage(img, 0, 0); + data = ctx.getImageData(0, 0, 1, ih).data; + // search image edge pixel position in case it is squashed vertically: + sy = 0; + ey = ih; + py = ih; + while (py > sy) { + alpha = data[(py - 1) * 4 + 3]; + if (alpha === 0) { + ey = py; + } else { + sy = py; + } + py = (ey + sy) >> 1; + } + return (py / ih) || 1; + }; + + // Renders image to canvas while working around iOS image scaling bugs: + // https://github.com/blueimp/JavaScript-Load-Image/issues/13 + loadImage.renderImageToCanvas = function (img, canvas, width, height) { + var iw = img.width, + ih = img.height, + ctx = canvas.getContext('2d'), + vertSquashRatio, + d = 1024, // size of tiling canvas + tmpCanvas = document.createElement('canvas'), + tmpCtx, + dw, + dh, + dx, + dy, + sx, + sy; + ctx.save(); + if (loadImage.detectSubsampling(img)) { + iw /= 2; + ih /= 2; + } + vertSquashRatio = loadImage.detectVerticalSquash(img, ih); + tmpCanvas.width = tmpCanvas.height = d; + tmpCtx = tmpCanvas.getContext('2d'); + dw = Math.ceil(d * width / iw); + dh = Math.ceil(d * height / ih / vertSquashRatio); + dy = 0; + sy = 0; + while (sy < ih) { + dx = 0; + sx = 0; + while (sx < iw) { + tmpCtx.clearRect(0, 0, d, d); + tmpCtx.drawImage(img, -sx, -sy); + ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh); + sx += d; + dx += dw; + } + sy += d; + dy += dh; + } + ctx.restore(); + tmpCanvas = tmpCtx = null; + }; + // Scales the given image (img or canvas HTML element) // using the given options. // Returns a canvas object if the browser supports canvas @@ -66,22 +169,27 @@ (options.minHeight || height) / height ); if (scale > 1) { - width = parseInt(width * scale, 10); - height = parseInt(height * scale, 10); + width = (width * scale) << 0; + height = (height * scale) << 0; } scale = Math.min( (options.maxWidth || width) / width, (options.maxHeight || height) / height ); if (scale < 1) { - width = parseInt(width * scale, 10); - height = parseInt(height * scale, 10); + width = (width * scale) << 0; + height = (height * scale) << 0; } if (img.getContext || (options.canvas && canvas.getContext)) { canvas.width = width; canvas.height = height; - canvas.getContext('2d') - .drawImage(img, 0, 0, width, height); + if (img._type === 'image/jpeg') { + loadImage + .renderImageToCanvas(img, canvas, width, height); + } else { + canvas.getContext('2d') + .drawImage(img, 0, 0, width, height); + } return canvas; } img.width = width; @@ -98,13 +206,12 @@ }; // Loads a given File object via FileReader interface, - // invokes the callback with a data url: + // invokes the callback with the event object (load or error). + // The result can be read via event.target.result: loadImage.readFile = function (file, callback) { if (window.FileReader && FileReader.prototype.readAsDataURL) { var fileReader = new FileReader(); - fileReader.onload = function (e) { - callback(e.target.result); - }; + fileReader.onload = fileReader.onerror = callback; fileReader.readAsDataURL(file); return fileReader; }