PageSourceSearch

https://gagnere.fr/lib/jquery_tiki/files.js

js gagnere.fr collected 2026-10-06 16:19:22 UTC 26,189 bytes, 893 lines download raw bytes

1
2(function ($) {
3	var handleFiles, ProgressBar, FileList, FileListInline;
4
5	$.fileTypeIcon = function (fileId, file) {
6		if(file.type.substring(0,6) == 'image/') {
7			return $('<img src="tiki-download_file.php?fileId=' + fileId + '&display&height=24" height="24">');
8		} else if(file.type == 'application/pdf') {
9			return $('<img height="16" width="16" title="application/pdf" alt="application/pdf" src="img/icons/mime/pdf.png">');
10		} else if(file.type.indexOf("sheet") != -1) {
11			return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/xls.png">');
12		} else if(file.type.indexOf("zip") != -1) {
13			return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/zip.png">');
14		} else if (file.type.substring(0,6) == 'video/') {
15			return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/flv.png">');
16		} else if (file.type.indexOf("word") != -1) {
17			return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/doc.png">');
18		} else {
19			return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/default.png">');
20		}
21	};
22
23	ProgressBar = function (options) {
24		var bar = this;
25		this.segments = [];
26		this.updateSegment = function (number, current, total) {
27			bar.segments[number] = [current, total];
28			bar.update();
29		};
30		this.update = function () {
31			var total = 0, current = 0;
32			$.each(bar.segments, function (k, item) {
33				current += item[0];
34				total += item[1];
35			});
36
37			options.progress(current, total);
38
39			if (current === total) {
40				options.done();
41			}
42		};
43	};
44
45	FileList = function (options) {
46		var $list = $(options.list);
47		this.clearErrors = function () {
48			$list.find('.text-danger').remove();
49		};
50		this.addError = function (file, message) {
51			var $li = $('<li>').appendTo($list);
52
53			$li.text(file.name);
54			$li.addClass('text-danger');
55			$li.append(' (' + (message ? message : tr('uploading failed')) + ')');
56		};
57		this.addFile = function (fileId, file) {
58			var $li = $('<li>').appendTo($list);
59
60			$li
61				.text(file.name)
62				.prepend($.fileTypeIcon(fileId, file));
63			$('<input type="hidden" name="file[]">')
64				.attr('value', fileId)
65				.appendTo($li)
66		};
67	};
68
69	FileListInline = function (options) {
70		var $list = $(options.list),
71			$form = $(options.form),
72			$files = [];
73		this.clearErrors = function () {
74			$list.find('.text-danger').remove();
75		};
76		this.addError = function (file) {
77			var $li = $('<li>').appendTo($form);
78
79			$li.text(file.name);
80			$li.addClass('text-danger');
81			$li.append(' (' + tr('uploading failed') + ')');
82		};
83		this.success = function(data){
84			$form.trigger('submit', [{files: $files}]);
85		};
86		this.addFile = function (fileId, file) {
87			file.fileId = fileId;
88			$files.push(file);
89
90			var action = $form.attr('data-action');
91			$.ajax(action, {
92				type: 'POST',
93				dataType: 'json',
94				data: {
95					files: [fileId]
96				},
97				success: this.success
98			});
99		};
100	};
101
102	handleFiles = function (input) {
103				
104		var files = input.files,
105			accept = input.accept,
106			galleryId = input.galleryId,
107			image_max_size_x = input.image_max_size_x,
108			image_max_size_y = input.image_max_size_y,
109			progressBar = input.progress,
110			fileList = input.list;
111
112		var uploadUrl = $.service('file', 'upload');
113
114		var restoreExif = function(sourceImageData, newImageData){
115			if (!sourceImageData.startsWith('data:image/jpeg;base64,')){
116				return newImageData;
117			}
118			var sourceImageSegments = MinifyJpeg.slice2Segments(MinifyJpeg.decode64(sourceImageData.replace("data:image/jpeg;base64,", "")));
119			var exifInfo = MinifyJpeg.getExif(sourceImageSegments);
120			var newImageBinArray = MinifyJpeg.insertExif(newImageData, exifInfo);
121			return "data:image/jpeg;base64," + MinifyJpeg.encode64(newImageBinArray);
122		};
123
124		$.each(files, function (k, file) {
125			var reader = new FileReader();
126	
127			progressBar.updateSegment(k, 0, file.size);
128			window.lastFile = file;
129
130			$(window).queue('process-upload', function () {
131				reader.onloadend = function (e) {
132					var xhr, provider, sendData, data, valid = true;
133
134					xhr = jQuery.ajaxSettings.xhr();
135					if (xhr.upload) {
136						xhr.upload.addEventListener('progress', function (e) {
137							if (e.lengthComputable) {
138								progressBar.updateSegment(k, e.loaded, e.total);
139							}
140						}, false);
141					}
142					provider = function () {
143						return xhr;
144					};
145
146					sendData = {
147						
148						type: 'POST',
149						url: uploadUrl,
150						xhr: provider,
151						dataType: 'json',
152						global: false, 	// prevent ajaxError in tiki-jquery.js from closing the dialogs, leading to lost edits
153						success: function (data) {
154							fileList.addFile(data.fileId, file);
155						},
156						error: function (jqXHR, textStatus, errorThrown) {
157							progressBar.updateSegment(k, 0, 0);
158							fileList.addError(file, errorThrown);
159						},
160						complete: function () {
161							$(window).dequeue('process-upload');
162						}
163					};
164
165					if (window.FormData) {
166						sendData.processData = false;
167						sendData.contentType = false;
168						sendData.cache = false;
169
170						sendData.data = new FormData;
171						sendData.data.append('galleryId', galleryId);
172						sendData.data.append('image_max_size_x', image_max_size_x);
173						sendData.data.append('image_max_size_y', image_max_size_y);
174						sendData.data.append('name',file.name);
175						
176						var waiting=false;
177						
178						//checking if image is uploaded to call resize function and resizing options are set by tracker field creator
179					    if(file.type.substring(0,6) == 'image/' && (image_max_size_x!='' || image_max_size_y!='')) {
180							waiting=true;
181							var imageData;
182						
183					    var picFile = e.target;
184                        imageData = picFile.result;
185				
186						  // imageData=resizeFile(e,imageData,parseInt(image_max_size_x),parseInt(image_max_size_y));
187						    var img = new Image();
188					        var blobImage=null;
189							img.src=imageData;
190	                           img.onload = function(){
191								   var width = parseInt(image_max_size_x);
192								   var height = parseInt(image_max_size_y);
193								   var image_x = parseInt(image_max_size_x);
194								   var image_y = parseInt(image_max_size_y);
195								   var ratio;
196								   if (img.width > image_x || img.height > image_y) {
197
198									   if (img.width > image_x) {
199										   width = image_x;
200										   ratio = image_x / img.width;
201                                height = Math.round(img.height * ratio);
202                            }
203
204                            if (height >image_y) {
205                                height =image_y;
206                                ratio = image_y / img.height;
207                                width = Math.round(img.width * ratio);
208                            }
209                       }
210					   else
211					   {
212						   width=img.width;
213						   height=img.height;
214						   }
215					        var canvas = $("<canvas/>").get(0);
216                            canvas.width = width;
217                            canvas.height = height;
218                            var context = canvas.getContext('2d');
219                            context.drawImage(img, 0, 0, width, height);
220						   var resizedImage = restoreExif(imageData, canvas.toDataURL('image/jpeg'));
221						   blobImage = dataURItoBlob(resizedImage);
222						   sendData.data.append('data',blobImage,file.name);
223						   $.ajax(sendData);
224									 }
225					           
226						}
227						else
228                           sendData.data.append('data', file);
229					} else {
230						data = e.target.result;
231						sendData.data = {
232							name: file.name,
233							size: file.size,
234							type: file.type,
235							data: data.substr(data.indexOf('base64') + 7),
236							galleryId: galleryId,
237							image_max_size_x:image_max_size_x,
238							image_max_size_y:image_max_size_y
239						};
240					}
241
242					if (accept) {
243						valid = file.type.match(new RegExp( ".?(" + accept.replace('*', '.*') + ")$", "i"));
244					}
245
246					if (valid && !waiting) {
247						$.ajax(sendData);
248					} else if(!valid) {
249						sendData.error(null);
250					}
251				};
252				reader.readAsDataURL(file);
253			});
254		});
255		$(window).dequeue('process-upload');
256	};
257
258	$(document).on('submit', 'form.file-uploader', function (e) {
259		e.preventDefault();
260	});
261
262	function doUpload($form, files) {
263		var progress, list;
264		
265		progress = new ProgressBar({
266			progress: function (current, total) {
267				var percentage = Math.round(current / total * 100);
268
269				$form.find('.progress').removeClass('hidden');
270				$form.find('.progress-bar')
271					.attr('aria-valuenow', percentage)
272					.width(percentage + '%');
273				$form.find('.progress-bar .sr-only .count')
274					.text(percentage);
275			},
276			done: function () {
277				$form.find('.progress').addClass('hidden');
278				$form.find('.progress-bar')
279					.attr('aria-valuenow', 0)
280					.width('0%');
281				$form.find('.progress-bar .sr-only .count')
282					.text('0%');
283			}
284		});
285
286		if($form.is(".inline")){
287			list = new FileListInline({
288				list: $form.parent().find('.file-uploader-result ul')[0],
289				form: $form
290			});
291		} else {
292			list = new FileList({
293				list: $form.parent().find('.file-uploader-result ul')[0]
294			});
295		}
296
297		list.clearErrors();
298
299		handleFiles({
300			accept: $form.find(':file').attr('accept'),
301			galleryId: $form.data('gallery-id'),
302			image_max_size_x:$form.data('image_max_size_x'),
303			image_max_size_y:$form.data('image_max_size_y'),
304			files: files,
305			progress: progress,
306			list: list
307		});
308	}
309
310	$(document).on('change', '.file-uploader input[type=file]', function () {
311		  
312		var $clone, $form = $(this).closest('.file-uploader'), progress, list;
313		if (this.files) {
314
315			doUpload($form, this.files);
316
317			$(this).val('');
318			$clone = $(this).clone(true);
319			$(this).replaceWith($clone);
320		}
321	});
322
323	if (window.FileReader) {
324		$(document).ready(function () {
325			$('.drop-message').show();
326		});
327		$(document).on('dragenter', '.file-uploader', function (e) {
328			e.preventDefault();
329			e.stopPropagation();
330			$(this).css('border', '2px dashed gray');
331			return false;
332		});
333		$(document).on('dragexit', '.file-uploader', function (e) {
334			e.preventDefault();
335			e.stopPropagation();
336			$(this).css('border', '');
337			return false;
338		});
339		$(document).on('dragover', '.file-uploader', function (e) {
340			e.preventDefault();
341			e.stopPropagation();
342			return false;
343		});
344		$(document).on('drop', '.file-uploader', function (e) {
345			var $form = $(this);
346
347			e.preventDefault();
348			e.stopPropagation();
349			$(this).css('border', '');
350
351			var dataTransfer = e.dataTransfer;
352			if (! dataTransfer) {
353				dataTransfer = e.originalEvent.dataTransfer;
354			}
355
356			if (dataTransfer && dataTransfer.files) {
357				doUpload($form, dataTransfer.files);
358			}
359			return false;
360		});
361	}
362
363	function browserRemoveFile(link)
364	{
365		var list = $(link).closest('ul');
366		$(link).closest('li').remove();
367
368		list.closest('.file-browser').trigger('selection-update');
369	}
370
371	function browserAddFile(link)
372	{
373		var content = $(link).closest('.media-body').clone(true),
374			icon = $(link).closest('.media, .panel').find('.media-object, .panel-body a').children('img').clone(true).width('16px'),
375			nav = $(link).closest('.file-browser').find('.selection ul'),
376			item = $('<li>'),
377			a = $('<a>').text($(link).text()),
378			id = $(link).data('object'),
379			limit = nav.closest('form').data('limit'),
380			current = nav.find('input[type=hidden]').filter(function () {
381				return parseInt($(this).val(), 10) === id;
382			});
383
384		if (current.length > 0) {
385			// Already in the list
386			browserRemoveFile(current[0]);
387			return;
388		}
389
390		if (limit === 1) {
391			nav.empty();
392		} else if (limit && nav.children('li').length >= limit) {
393			alert(nav.closest('form').data('limit-reached-message'));
394			return;
395		}
396
397		a
398			.prepend(' ')
399			.prepend(icon);
400		item.append(a);
401		nav.append(item);
402
403		item.append($('<input type="hidden" name="file[]">')
404			.attr('value', id));
405
406		nav.closest('.file-browser').trigger('selection-update');
407	}
408
409	$(document).on('selection-update', '.file-browser', function (e) {
410		var selection = $('.selection input[type=hidden]', this).map(function () {
411			return parseInt($(this).val(), 10);
412		});
413
414		$('.gallery-list .media-heading a, .gallery-list .panel-body a', this).each(function () {
415			var id = $(this).data('object');
416			$(this).closest('.media').toggleClass('bg-info', -1 !== $.inArray(id, selection));
417			$(this).closest('.panel').toggleClass('panel-info', -1 !== $.inArray(id, selection));
418		});
419		$('.selection', this).toggleClass('hidden', selection.length === 0);
420	});
421
422	$(document).on('click', '.file-browser .gallery-list .pagination a', function (e) {
423		e.preventDefault();
424		$(this).closest('.modal').animate({ scrollTop: 0 }, 'slow');
425		$(this).closest('.gallery-list')
426			.tikiModal(tr('Loading...'))
427			.load($(this).attr('href'), function () {
428				$(this).tikiModal('');
429				$(this).closest('.file-browser').trigger('selection-update');
430			});
431	});
432
433	$(document).on('click', '.file-browser .gallery-list .media-heading a, .file-browser .gallery-list .panel-body a', function (e) {
434		e.preventDefault();
435		e.stopPropagation();
436		browserAddFile(this);
437	});
438	$(document).on('click', '.file-browser .gallery-list .media, .file-browser .gallery-list .panel', function (e) {
439		e.preventDefault();
440		$('.media-heading a, .panel-body a', this).click();
441	});
442
443	$(document).on('click', '.file-browser .selection a', function (e) {
444		e.preventDefault();
445		browserRemoveFile(this);
446	});
447
448	$(document).on('submit', '.file-browser .form-inline', function (e) {
449		e.preventDefault();
450		$(this).closest('.file-browser').find('.gallery-list')
451			.tikiModal(tr('Loading...'))
452			.load($(this).attr('action'), $(this).serialize(), function () {
453				$(this).tikiModal('');
454				$(this).closest('.file-browser').trigger('selection-update');
455			});
456	});
457
458	$(document).on('click', '.file-browser .submit .upload-files', function (e) {
459		var $list = $(this).closest('.file-browser').find('.selection ul'),
460			handler = $.clickModal({
461				success: function (data) {
462					$.each(data.files, function (k, file) {
463						$('<li>')
464							.append($('<a href="#">')
465								.data('object', file.fileId)
466								.data('type', 'file')
467								.text(file.label))
468							.append($('<input type="hidden" name="file[]">')
469								.attr('value', file.fileId))
470							.appendTo($list);
471
472						$list.closest('.file-browser').trigger('selection-update');
473					});
474					$.closeModal();
475				}
476			});
477
478		handler.apply(this, arguments);
479	});
480
481	// File selector component
482	$(document).on('click', '.file-selector a', function () {
483		if (! $(this).data('initial-href')) {
484			$(this).data('initial-href', $(this).attr('href'));
485		}
486
487		// Before the dialog handler triggers, replace the href with one including current files
488		$(this).attr('href', $(this).data('initial-href') + '&file=' + $(this).parent().children('input').val());
489	});
490	$(document).on('click', '.file-selector a', $.clickModal({
491		size: 'modal-lg',
492		success: function (data) {
493			var files = [];
494			$.each(data.files, function (k, f) {
495				files.push(f.fileId);
496			});
497			$(this).parent().children('input').val(files.join(','));
498			$(this).text($(this).text().replace(/\d+/, files.length));
499			$.closeModal();
500		}
501	}));
502})(jQuery);
503
504
505    function resizeFile(e,imageData,image_x,image_y) {
506        
507                    //var picReader = new FileReader();
508                    //picReader.readAsDataURL(file);
509				     return blobImage;
510}
511    
512function dataURItoBlob(dataURI) {
513	
514	
515    // convert base64/URLEncoded data component to raw binary data held in a string
516    var byteString;
517    if (dataURI.split(',')[0].indexOf('base64') >= 0)
518        byteString = atob(dataURI.split(',')[1]);
519    else
520        byteString = unescape(dataURI.split(',')[1]);
521
522    // separate out the mime component
523    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
524
525    // write the bytes of the string to a typed array
526    var ia = new Uint8Array(byteString.length);
527    for (var i = 0; i < byteString.length; i++) {
528        ia[i] = byteString.charCodeAt(i);
529    }
530
531    return new Blob([ia],{ type:'image/jpeg' });
532}
533
534/* To minify a jpeg image without loosing EXIF.
535 * TESTED(24/01/2013): FireFox, GoogleChrome, IE10, Opera
536 * Copyright (c) 2013 hMatoba
537 * Released under the MIT license : https://github.com/hMatoba/MinifyJpegAsync/blob/master/LICENSE.txt
538 *
539 * To minify jpeg image:
540 *     minified = MinifyJpeg.minify(image, length);
541 *     xhr.send(minified.buffer);
542 *     enc = "data:image/jpeg;base64," + MinifyJpeg.encode64(minified);
543 *     html = '<img src="' + enc + '">';
544 * MinifyJpeg.minify() - return Uint8Array
545 * image - image base64encoded, it can be obtained "FileReader().readAsDataURL(f)"
546 * length - the long side length of the rectangle
547 * MinifyJpeg.encode64() - convert array to base64encoded string
548 */
549var MinifyJpeg = (function()
550{
551/*
552  if (typeof JpegImage == "undefined")
553  {
554    throw new ReferenceError("Load jpg.js!");
555  }
556*/
557  var that = {};
558
559  that.KEY_STR = "ABCDEFGHIJKLMNOP" +
560    "QRSTUVWXYZabcdef" +
561    "ghijklmnopqrstuv" +
562    "wxyz0123456789+/" +
563    "=";
564
565  that.SOF = [192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207];
566
567  that.minify = function(image, new_size)
568  {
569    if (image instanceof ArrayBuffer)
570    {
571      if (image[0] == 255 && image[1] == 216)
572      {
573        var rawImage = [];
574        for (var i=0; i<image.byteLength; i++)
575        {
576          rawImage[i] = image[i];
577        }
578      }
579      else
580      {
581        throw "MinifyJpeg.minify got a not JPEG data";
582      }
583    }
584    else if (typeof(image) == "string")
585    {
586      if (!image.match("data:image/jpeg;base64,"))
587      {
588        throw "MinifyJpeg.minify got a not JPEG data";
589      }
590      else
591      {
592        var rawImage = that.decode64(image.replace("data:image/jpeg;base64,", ""));
593      }
594    }
595    else
596    {
597      throw "First argument must be 'DataURL string' or ArrayBuffer.";
598    }
599
600    var segments = that.slice2Segments(rawImage);
601    var NEW_SIZE = parseInt(new_size);
602    var size = that.imageSizeFromSegments(segments);
603    var chouhen = (size[0] >= size[1]) ? size[0] : size[1];
604    if (chouhen < NEW_SIZE)
605    {
606      return new Uint8Array(rawImage);
607    }
608
609    var exif = that.getExif(segments);
610    var resized = that.resizeImage(rawImage, segments, NEW_SIZE);
611
612    if (exif.length)
613    {
614      var newImage = that.insertExif(resized, exif);
615    }
616    else
617    {
618      var newImage = new Uint8Array(that.decode64(resized.replace("data:image/jpeg;base64,", "")));
619    }
620
621    return newImage;
622  };
623
624  that.getImageSize = function(imageArray)
625  {
626    var segments = that.slice2Segments(imageArray);
627    return that.imageSizeFromSegments(segments);
628  };
629
630  that.slice2Segments = function(rawImageArray)
631  {
632    var head = 0,
633      segments = [];
634
635    while (1)
636    {
637      if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218)
638      {
639        break;
640      }
641      if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)
642      {
643        head += 2;
644      }
645      else
646      {
647        var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],
648          endPoint = head + length + 2,
649          seg = rawImageArray.slice(head, endPoint);
650        segments.push(seg);
651        head = endPoint;
652      }
653      if (head > rawImageArray.length)
654      {
655        break;
656      }
657    }
658
659    return segments;
660  };
661
662  that.imageSizeFromSegments = function(segments)
663  {
664    for  (var x=0; x<segments.length; x++)
665    {
666      var seg = segments[x];
667      if (that.SOF.indexOf(seg[1]) >= 0)
668      {
669        var height = seg[5] * 256 + seg[6],
670          width = seg[7] * 256 + seg[8];
671        break;
672      }
673    }
674    return [width, height];
675  };
676
677  that.encode64 = function(input)
678  {
679    var output = "",
680      chr1, chr2, chr3 = "",
681      enc1, enc2, enc3, enc4 = "",
682      i = 0;
683
684    do {
685      chr1 = input[i++];
686      chr2 = input[i++];
687      chr3 = input[i++];
688
689      enc1 = chr1 >> 2;
690      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
691      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
692      enc4 = chr3 & 63;
693
694      if (isNaN(chr2)) {
695        enc3 = enc4 = 64;
696      } else if (isNaN(chr3)) {
697        enc4 = 64;
698      }
699
700      output += that.KEY_STR.charAt(enc1) +
701        that.KEY_STR.charAt(enc2) +
702        that.KEY_STR.charAt(enc3) +
703        that.KEY_STR.charAt(enc4);
704      chr1 = chr2 = chr3 = "";
705      enc1 = enc2 = enc3 = enc4 = "";
706    } while (i < input.length);
707    return output;
708  };
709
710  that.decode64 = function(input) {
711    var output = "",
712      chr1, chr2, chr3 = "",
713      enc1, enc2, enc3, enc4 = "",
714      i = 0,
715      buf = [];
716
717    // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
718    var base64test = /[^A-Za-z0-9\+\/\=]/g;
719    if (base64test.exec(input)) {
720      alert("There were invalid base64 characters in the input text.\n" +
721        "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
722        "Expect errors in decoding.");
723    }
724    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
725
726    do {
727      enc1 = that.KEY_STR.indexOf(input.charAt(i++));
728      enc2 = that.KEY_STR.indexOf(input.charAt(i++));
729      enc3 = that.KEY_STR.indexOf(input.charAt(i++));
730      enc4 = that.KEY_STR.indexOf(input.charAt(i++));
731
732      chr1 = (enc1 << 2) | (enc2 >> 4);
733      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
734      chr3 = ((enc3 & 3) << 6) | enc4;
735
736      buf.push(chr1);
737
738      if (enc3 != 64) {
739        buf.push(chr2);
740      }
741      if (enc4 != 64) {
742        buf.push(chr3);
743      }
744
745      chr1 = chr2 = chr3 = "";
746      enc1 = enc2 = enc3 = enc4 = "";
747
748    } while (i < input.length);
749
750    return buf;
751  };
752
753  that.resizeImage = function(rawImage, segments, NEW_SIZE)
754  {
755    var size = that.imageSizeFromSegments(segments),
756      width = size[0],
757      height = size[1],
758      chouhen = (width>=height) ? width : height,
759      newSize = NEW_SIZE,
760      resizing = 1,
761      scale = parseFloat(newSize) / chouhen,
762      newWidth = parseInt(parseFloat(newSize) / chouhen * width),
763      newHeight = parseInt(parseFloat(newSize) / chouhen * height);
764
765    if (resizing == 1) // bilinear
766    {
767      var canvas = document.createElement('canvas');
768      canvas.width = width;
769      canvas.height = height;
770
771      var jpe = new JpegImage(),
772        ctx = canvas.getContext("2d"),
773        srcImg = ctx.getImageData(0, 0, width, height);
774      jpe.parse(new Uint8Array(rawImage));
775      jpe.copyToImageData(srcImg);
776
777      var newCanvas = document.createElement('canvas');
778      newCanvas.width = newWidth;
779      newCanvas.height = newHeight;
780      var newCtx = newCanvas.getContext("2d");
781      var destImg = newCtx.createImageData(newWidth, newHeight);
782      that.bilinear(srcImg, destImg, scale);
783
784      newCtx.putImageData(destImg, 0, 0);
785      var resizedImage = newCanvas.toDataURL("image/jpeg");
786    }
787    else // nearest neighbor?
788    {
789      var canvas = document.createElement('canvas');
790      canvas.width = newWidth;
791      canvas.height = newHeight;
792
793      var jpe = new JpegImage();
794      ctx = canvas.getContext("2d");
795      d = ctx.getImageData(0, 0, newWidth, newHeight);
796      jpe.parse(new Uint8Array(rawImage));
797      jpe.copyToImageData(d);
798      ctx.putImageData(d, 0, 0);
799
800      var resizedImage = canvas.toDataURL("image/jpeg");
801    }
802
803    return resizedImage;
804  };
805
806  that.getExif = function(segments)
807  {
808    var seg;
809    for (var x=0; x<segments.length; x++)
810    {
811      seg = segments[x];
812      if (seg[0] == 255 & seg[1] == 225) //(ff e1)
813      {
814        return seg;
815      }
816    }
817    return [];
818  }
819
820  that.insertExif = function(imageStr, exifArray)
821  {
822    var buf = that.decode64(imageStr.replace("data:image/jpeg;base64,", "")),
823      separatePoint = buf.indexOf(255,3),
824      mae = buf.slice(0, separatePoint),
825      ato = buf.slice(separatePoint),
826      array = mae.concat(exifArray, ato);
827
828    aBuffer = new Uint8Array(array);
829
830    return aBuffer;
831  };
832
833  // compute vector index from matrix one
834  that.ivect = function (ix, iy, w) {
835    // byte array, r,g,b,a
836    return((ix + w * iy) * 4);
837  };
838
839  that.bilinear = function (srcImg, destImg, scale) {
840    // c.f.: wikipedia english article on bilinear interpolation
841    //log.debug("in bilinear");
842    // taking the unit square
843    function inner(f00, f10, f01, f11, x, y) {
844      var un_x = 1.0 - x; var un_y = 1.0 - y;
845      return (f00 * un_x * un_y + f10 * x * un_y + f01 * un_x * y + f11 * x * y);
846    }
847    var srcWidth = srcImg.width;
848    var srcHeight = srcImg.height;
849    var srcData = srcImg.data;
850    var dstData = destImg.data;
851    var i, j;
852    var iyv, iy0, iy1, ixv, ix0, ix1;
853    var idxD, idxS00, idxS10, idxS01, idxS11;
854    var dx, dy;
855    var r, g, b, a;
856    for (i = 0; i < destImg.height; ++i) {
857      iyv = (i + 0.5) / scale - 0.5;
858      iy0 = Math.floor(iyv);
859      iy1 = ( Math.ceil(iyv) > (srcHeight-1) ? (srcHeight-1) : Math.ceil(iyv) );
860      for (j = 0; j < destImg.width; ++j) {
861        ixv = (j + 0.5) / scale - 0.5;
862        ix0 = Math.floor(ixv);
863        ix1 = ( Math.ceil(ixv) > (srcWidth-1) ? (srcWidth-1) : Math.ceil(ixv) );
864        idxD = that.ivect(j, i, destImg.width);
865        idxS00 = that.ivect(ix0, iy0, srcWidth);
866        idxS10 = that.ivect(ix1, iy0, srcWidth);
867        idxS01 = that.ivect(ix0, iy1, srcWidth);
868        idxS11 = that.ivect(ix1, iy1, srcWidth);
869        // log.debug(sprintf("bilinear: idx: D: %d, S00: %d, S10: %d, S01: %d, S11: %d", idxD, idxS00, idxS10, idxS01, idxS11));
870        dx = ixv - ix0; dy = iyv - iy0;
871
872        //r
873        dstData[idxD] = inner(srcData[idxS00], srcData[idxS10],
874          srcData[idxS01], srcData[idxS11], dx, dy);
875
876        //g
877        dstData[idxD+1] = inner(srcData[idxS00+1], srcData[idxS10+1],
878          srcData[idxS01+1], srcData[idxS11+1], dx, dy);
879
880        //b
881        dstData[idxD+2] = inner(srcData[idxS00+2], srcData[idxS10+2],
882          srcData[idxS01+2], srcData[idxS11+2], dx, dy);
883
884        //a
885        dstData[idxD+3] = inner(srcData[idxS00+3], srcData[idxS10+3],
886          srcData[idxS01+3], srcData[idxS11+3], dx, dy);
887
888        // log.debug(sprintf("pixel: j:%d, i:%d; r:%d, g:%d, b:%d", j, i, r, g, b));
889      }
890    }
891  };
892  return that;
893})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.