buildfileupload.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. jQuery.extend({
  2. buildfileupload: function(s) {
  3. try {
  4. var reader = new FileReader();
  5. var canvaszoom = false;
  6. if(1 || (s.maxfilesize && s.files[0].size > s.maxfilesize * 1024)) {
  7. canvaszoom = true;
  8. }
  9. var picupload = function(picdata) {
  10. if(!XMLHttpRequest.prototype.sendAsBinary){
  11. XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
  12. function byteValue(x) {
  13. return x.charCodeAt(0) & 0xff;
  14. }
  15. var ords = Array.prototype.map.call(datastr, byteValue);
  16. var ui8a = new Uint8Array(ords);
  17. this.send(ui8a.buffer);
  18. }
  19. }
  20. var xhr = new XMLHttpRequest(),
  21. file = s.files[0],
  22. index = 0,
  23. start_time = new Date().getTime(),
  24. boundary = '------multipartformboundary' + (new Date).getTime(),
  25. builder;
  26. builder = jQuery.getbuilder(s, file.name, picdata, boundary);
  27. if(s.uploadpercent) {
  28. xhr.upload.onprogress = function(e) {
  29. if(e.lengthComputable) {
  30. var percent = Math.ceil((e.loaded / e.total) * 100);
  31. $('#' + s.uploadpercent).html(percent + '%');
  32. }
  33. };
  34. }
  35. xhr.open("POST", s.uploadurl, true);
  36. xhr.setRequestHeader('content-type', 'multipart/form-data; boundary='
  37. + boundary);
  38. xhr.sendAsBinary(builder);
  39. xhr.onerror = function() {
  40. s.error();
  41. };
  42. xhr.onabort = function() {
  43. s.error();
  44. };
  45. xhr.ontimeout = function() {
  46. s.error();
  47. };
  48. xhr.onload = function() {
  49. if(xhr.responseText) {
  50. s.success(xhr.responseText);
  51. }
  52. };
  53. };
  54. var getorientation = function(binfile) {
  55. function getbyteat(offset) {
  56. return binfile.charCodeAt(offset) & 0xFF;
  57. }
  58. function getbytesat(offset, length) {
  59. var bytes = [];
  60. for(var i=0; i<length; i++) {
  61. bytes[i] = binfile.charCodeAt((offset + i)) & 0xFF;
  62. }
  63. return bytes;
  64. }
  65. function getshortat(offset, bigendian) {
  66. var shortat = bigendian ?
  67. (getbyteat(offset) << 8) + getbyteat(offset + 1)
  68. : (getbyteat(offset + 1) << 8) + getbyteat(offset);
  69. if(shortat < 0) {
  70. shortat += 65536;
  71. }
  72. return shortat;
  73. }
  74. function getlongat(offset, bigendian) {
  75. var byte1 = getbyteat(offset);
  76. var byte2 = getbyteat(offset + 1);
  77. var byte3 = getbyteat(offset + 2);
  78. var byte4 = getbyteat(offset + 3);
  79. var longat = bigendian ?
  80. (((((byte1 << 8) + byte2) << 8) + byte3) << 8) + byte4
  81. : (((((byte4 << 8) + byte3) << 8) + byte2) << 8) + byte1;
  82. if(longat < 0) longat += 4294967296;
  83. return longat;
  84. }
  85. function getslongat(offset, bigendian) {
  86. var ulongat = getlongat(offset, bigendian);
  87. if(ulongat > 2147483647) {
  88. return ulongat - 4294967296;
  89. } else {
  90. return ulongat;
  91. }
  92. }
  93. function getstringat(offset, length) {
  94. var str = [];
  95. var bytes = getbytesat(offset, length);
  96. for(var i=0; i<length; i++) {
  97. str[i] = String.fromCharCode(bytes[i]);
  98. }
  99. return str.join('');
  100. }
  101. function readtagvalue(entryoffset, tiffstart, dirstart, bigend) {
  102. var type = getshortat(entryoffset + 2, bigend);
  103. var numvalues = getlongat(entryoffset + 4, bigend);
  104. var valueoffset = getlongat(entryoffset + 8, bigend) + tiffstart;
  105. var offset, vals;
  106. switch(type) {
  107. case 1:
  108. case 7:
  109. if(numvalues == 1) {
  110. return getbyteat(entryoffset + 8, bigend);
  111. } else {
  112. offset = numvalues > 4 ? valueoffset : (entryoffset + 8);
  113. vals = [];
  114. for(var n=0; n<numvalues; n++) {
  115. vals[n] = getbyteat(offset + n);
  116. }
  117. return vals;
  118. }
  119. case 2:
  120. offset = numvalues > 4 ? valueoffset : (entryoffset + 8);
  121. return getstringat(offset, numvalues - 1);
  122. case 3:
  123. if(numvalues == 1) {
  124. return getshortat(entryoffset + 8, bigend);
  125. } else {
  126. offset = numvalues > 2 ? valueoffset : (entryoffset + 8);
  127. vals = [];
  128. for(var n=0;n<numvalues; n++) {
  129. vals[n] = getshortat(offset + 2 * n, bigend);
  130. }
  131. return vals;
  132. }
  133. case 4:
  134. if(numvalues == 1) {
  135. return getlongat(entryoffset + 8, bigend);
  136. } else {
  137. vals = [];
  138. for(var n=0; n<numvalues; i++) {
  139. vals[n] = getlongat(valueoffset + 4 * n, bigend);
  140. }
  141. return vals;
  142. }
  143. case 5:
  144. if(numvalues == 1) {
  145. var numerator = getlongat(valueoffset, bigend);
  146. var denominator = getlongat(valueoffset + 4, bigend);
  147. var val = new Number(numerator / denominator);
  148. val.numerator = numerator;
  149. val.denominator = denominator;
  150. return val;
  151. } else {
  152. vals = [];
  153. for(var n=0; n<numvalues; n++) {
  154. var numerator = getlongat(valueoffset + 8*n, bigend);
  155. var denominator = getlongat(valueoffset+4 + 8*n, bigend);
  156. vals[n] = new Number(numerator / denominator);
  157. vals[n].numerator = numerator;
  158. vals[n].denominator = denominator;
  159. }
  160. return vals;
  161. }
  162. case 9:
  163. if(numvalues == 1) {
  164. return getslongat(entryoffset + 8, bigend);
  165. } else {
  166. vals = [];
  167. for(var n=0;n<numvalues; n++) {
  168. vals[n] = getslongat(valueoffset + 4 * n, bigend);
  169. }
  170. return vals;
  171. }
  172. case 10:
  173. if(numvalues == 1) {
  174. return getslongat(valueoffset, bigend) / getslongat(valueoffset+4, bigend);
  175. } else {
  176. vals = [];
  177. for(var n=0; n<numvalues; n++) {
  178. vals[n] = getslongat(valuesoffset + 8*n, bigend) / getslongat(valueoffset+4 + 8*n, bigend);
  179. }
  180. return vals;
  181. }
  182. }
  183. }
  184. function readtags(tiffstart, dirstart, strings, bigend) {
  185. var entries = getshortat(dirstart, bigend);
  186. var tags = {}, entryofffset, tag;
  187. for(var i=0; i<entries; i++) {
  188. entryoffset = dirstart + i *12 + 2;
  189. tag = strings[getshortat(entryoffset, bigend)];
  190. tags[tag] = readtagvalue(entryoffset, tiffstart, dirstart, bigend);
  191. }
  192. return tags;
  193. }
  194. function readexifdata(start) {
  195. if(getstringat(start, 4) != 'Exif') {
  196. return false;
  197. }
  198. var bigend;
  199. var tags, tag;
  200. var tiffoffset = start + 6;
  201. if(getshortat(tiffoffset) == 0x4949) {
  202. bigend = false;
  203. } else if(getshortat(tiffoffset) == 0x4D4D) {
  204. bigend = true;
  205. } else {
  206. return false;
  207. }
  208. if(getshortat(tiffoffset + 2, bigend) != 0x002A) {
  209. return false;
  210. }
  211. if(getlongat(tiffoffset + 4, bigend) != 0x00000008) {
  212. return false;
  213. }
  214. var tifftags = {
  215. 0x0112 : "Orientation"
  216. };
  217. tags = readtags(tiffoffset, tiffoffset + 8, tifftags, bigend);
  218. return tags;
  219. }
  220. if(getbyteat(0) != 0xFF || getbyteat(1) != 0xD8) {
  221. return false;
  222. }
  223. var offset = 2;
  224. var length = binfile.length;
  225. var marker;
  226. while(offset < length) {
  227. if(getbyteat(offset) != 0xFF) {
  228. return false;
  229. }
  230. marker = getbyteat(offset + 1);
  231. if(marker == 22400 || marker == 225) {
  232. return readexifdata(offset + 4);
  233. } else {
  234. offset += 2 + getshortat(offset + 2, true);
  235. }
  236. }
  237. };
  238. var detectsubsampling = function(img, imgwidth, imgheight) {
  239. if(imgheight * imgwidth > 1024 * 1024) {
  240. var tmpcanvas = document.createElement('canvas');
  241. tmpcanvas.width = tmpcanvas.height = 1;
  242. var tmpctx = tmpcanvas.getContext('2d');
  243. tmpctx.drawImage(img, -imgwidth + 1, 0);
  244. return tmpctx.getImageData(0, 0, 1, 1).data[3] === 0;
  245. } else {
  246. return false;
  247. }
  248. };
  249. var detectverticalsquash = function(img, imgheight) {
  250. var tmpcanvas = document.createElement('canvas');
  251. tmpcanvas.width = 1;
  252. tmpcanvas.height = imgheight;
  253. var tmpctx = tmpcanvas.getContext('2d');
  254. tmpctx.drawImage(img, 0, 0);
  255. var data = tmpctx.getImageData(0, 0, 1, imgheight).data;
  256. var sy = 0;
  257. var ey = imgheight;
  258. var py = imgheight;
  259. while(py > sy) {
  260. var alpha = data[(py - 1) * 4 + 3];
  261. if(alpha === 0) {
  262. ey = py;
  263. } else {
  264. sy = py;
  265. }
  266. py = (ey + sy) >> 1;
  267. }
  268. var ratio = py / imgheight;
  269. return (ratio === 0) ? 1 : ratio;
  270. };
  271. var transformcoordinate = function(canvas, ctx, width, height, orientation) {
  272. switch(orientation) {
  273. case 5:
  274. case 6:
  275. case 7:
  276. case 8:
  277. canvas.width = height;
  278. canvas.height = width;
  279. break;
  280. default:
  281. canvas.width = width;
  282. canvas.height = height;
  283. }
  284. switch(orientation) {
  285. case 2:
  286. ctx.translate(width, 0);
  287. ctx.scale(-1, 1);
  288. break;
  289. case 3:
  290. ctx.translate(width, height);
  291. ctx.rotate(Math.PI);
  292. break;
  293. case 4:
  294. ctx.translate(0, height);
  295. ctx.scale(1, -1);
  296. break;
  297. case 5:
  298. ctx.rotate(0.5 * Math.PI);
  299. ctx.scale(1, -1);
  300. break;
  301. case 6:
  302. ctx.rotate(0.5 * Math.PI);
  303. ctx.translate(0, -height);
  304. break;
  305. case 7:
  306. ctx.rotate(0.5 * Math.PI);
  307. ctx.translate(width, -height);
  308. ctx.scale(-1, 1);
  309. break;
  310. case 8:
  311. ctx.rotate(-0.5 * Math.PI);
  312. ctx.translate(-width, 0);
  313. break;
  314. }
  315. };
  316. var maxheight = 500;
  317. var maxwidth = 500;
  318. var canvas = document.createElement('canvas');
  319. var ctx = canvas.getContext('2d');
  320. var img = new Image();
  321. img.onload = function() {
  322. $this = $(this);
  323. var imgwidth = this.width ? this.width : $this.width();
  324. var imgheight = this.height ? this.height : $this.height();
  325. var canvaswidth = maxwidth;
  326. var canvasheight = maxheight;
  327. var newwidth = imgwidth;
  328. var newheight = imgheight;
  329. if(imgwidth/imgheight <= canvaswidth/canvasheight && imgheight >= canvasheight) {
  330. newheight = canvasheight;
  331. newwidth = Math.ceil(canvasheight/imgheight*imgwidth);
  332. } else if(imgwidth/imgheight > canvaswidth/canvasheight && imgwidth >= canvaswidth) {
  333. newwidth = canvaswidth;
  334. newheight = Math.ceil(canvaswidth/imgwidth*imgheight);
  335. }
  336. ctx.save();
  337. var imgfilebinary = this.src.replace(/data:.+;base64,/, '');
  338. if(typeof atob == 'function') {
  339. imgfilebinary = atob(imgfilebinary);
  340. } else {
  341. imgfilebinary = jQuery.base64decode(imgfilebinary);
  342. }
  343. var orientation = getorientation(imgfilebinary);
  344. orientation = orientation.Orientation;
  345. if(detectsubsampling(this, imgwidth, imgheight)) {
  346. imgheight = imgheight / 2;
  347. imgwidth = imgwidth / 2;
  348. }
  349. var vertsquashratio = detectverticalsquash(this, imgheight);
  350. transformcoordinate(canvas, ctx, newwidth, newheight, orientation);
  351. ctx.drawImage(this, 0, 0, imgwidth, imgheight, 0, 0, newwidth, newheight/vertsquashratio);
  352. ctx.restore();
  353. var newdataurl = canvas.toDataURL(s.files[0].type).replace(/data:.+;base64,/, '');
  354. if(typeof atob == 'function') {
  355. picupload(atob(newdataurl));
  356. } else {
  357. picupload(jQuery.base64decode(newdataurl));
  358. }
  359. };
  360. reader.index = 0;
  361. reader.onloadend = function(e) {
  362. if(canvaszoom) {
  363. img.src = e.target.result;
  364. } else {
  365. picupload(e.target.result);
  366. }
  367. return;
  368. };
  369. if(canvaszoom) {
  370. reader.readAsDataURL(s.files[0]);
  371. } else {
  372. reader.readAsBinaryString(s.files[0]);
  373. }
  374. } catch(err) {
  375. return s.error();
  376. }
  377. return;
  378. },
  379. getbuilder: function(s, filename, filedata, boundary) {
  380. var dashdash = '--',
  381. crlf = '\r\n',
  382. builder = '';
  383. for(var i in s.uploadformdata) {
  384. builder += dashdash;
  385. builder += boundary;
  386. builder += crlf;
  387. builder += 'Content-Disposition: form-data; name="' + i + '"';
  388. builder += crlf;
  389. builder += crlf;
  390. builder += s.uploadformdata[i];
  391. builder += crlf;
  392. }
  393. builder += dashdash;
  394. builder += boundary;
  395. builder += crlf;
  396. builder += 'Content-Disposition: form-data; name="' + s.uploadinputname + '"';
  397. builder += '; filename="' + filename + '"';
  398. builder += crlf;
  399. builder += 'Content-Type: application/octet-stream';
  400. builder += crlf;
  401. builder += crlf;
  402. builder += filedata;
  403. builder += crlf;
  404. builder += dashdash;
  405. builder += boundary;
  406. builder += dashdash;
  407. builder += crlf;
  408. return builder;
  409. }
  410. });
  411. jQuery.extend({
  412. base64encode: function(input) {
  413. var output = '';
  414. var chr1, chr2, chr3 = '';
  415. var enc1, enc2, enc3, enc4 = '';
  416. var i = 0;
  417. do {
  418. chr1 = input.charCodeAt(i++);
  419. chr2 = input.charCodeAt(i++);
  420. chr3 = input.charCodeAt(i++);
  421. enc1 = chr1 >> 2;
  422. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  423. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  424. enc4 = chr3 & 63;
  425. if (isNaN(chr2)){
  426. enc3 = enc4 = 64;
  427. } else if (isNaN(chr3)){
  428. enc4 = 64;
  429. }
  430. output = output+this._keys.charAt(enc1)+this._keys.charAt(enc2)+this._keys.charAt(enc3)+this._keys.charAt(enc4);
  431. chr1 = chr2 = chr3 = '';
  432. enc1 = enc2 = enc3 = enc4 = '';
  433. } while (i < input.length);
  434. return output;
  435. },
  436. base64decode: function(input) {
  437. var output = '';
  438. var chr1, chr2, chr3 = '';
  439. var enc1, enc2, enc3, enc4 = '';
  440. var i = 0;
  441. if (input.length%4!=0){
  442. return '';
  443. }
  444. var base64test = /[^A-Za-z0-9\+\/\=]/g;
  445. if (base64test.exec(input)){
  446. return '';
  447. }
  448. do {
  449. enc1 = this._keys.indexOf(input.charAt(i++));
  450. enc2 = this._keys.indexOf(input.charAt(i++));
  451. enc3 = this._keys.indexOf(input.charAt(i++));
  452. enc4 = this._keys.indexOf(input.charAt(i++));
  453. chr1 = (enc1 << 2) | (enc2 >> 4);
  454. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  455. chr3 = ((enc3 & 3) << 6) | enc4;
  456. output = output + String.fromCharCode(chr1);
  457. if (enc3 != 64){
  458. output+=String.fromCharCode(chr2);
  459. }
  460. if (enc4 != 64){
  461. output+=String.fromCharCode(chr3);
  462. }
  463. chr1 = chr2 = chr3 = '';
  464. enc1 = enc2 = enc3 = enc4 = '';
  465. } while (i < input.length);
  466. return output;
  467. },
  468. _keys: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
  469. });