You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

953 lines
35 KiB

(function ($) {
var handleFiles, ProgressBar, FileList, FileListInline;
$.fileTypeIcon = function (fileId, file) {
if (typeof file.type == 'undefined') {
return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/default.png">');
} else if(file.type.substring(0,6) == 'image/') {
return $('<img src="tiki-download_file.php?fileId=' + fileId + '&display&y=24" height="24">');
} else if(file.type == 'application/pdf') {
return $('<img height="16" width="16" title="application/pdf" alt="application/pdf" src="img/icons/mime/pdf.png">');
} else if(file.type.indexOf("sheet") != -1) {
return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/xls.png">');
} else if(file.type.indexOf("zip") != -1) {
return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/zip.png">');
} else if (file.type.substring(0,6) == 'video/') {
return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/flv.png">');
} else if (file.type.indexOf("word") != -1) {
return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/doc.png">');
} else {
return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/default.png">');
}
};
ProgressBar = function (options) {
var bar = this;
this.segments = [];
this.updateSegment = function (number, current, total) {
bar.segments[number] = [current, total];
bar.update();
};
this.update = function () {
var total = 0, current = 0;
$.each(bar.segments, function (k, item) {
current += item[0];
total += item[1];
});
options.progress(current, total);
if (current === total) {
options.done();
}
};
};
FileList = function (options) {
var $list = $(options.list);
this.clearErrors = function () {
$list.find('.text-danger').remove();
};
this.addError = function (file, message) {
var $li = $('<li>').appendTo($list);
$li.text(file.name);
$li.addClass('text-danger');
$li.append(' (' + (message ? message : tr('uploading failed')) + ')');
};
this.addFile = function (fileId, file, title) {
// called for "upload in modal" tracker Files fields when file dropped or picked from the file dialog
var $li = $('<li>').addClass("row mb-4").appendTo($list);
var label = file.name;
if (title) {
label = title;
}
$("<div>").addClass("col-sm-12").text(label)
.prepend($.fileTypeIcon(fileId, file).css("margin-right", "1em"))
.appendTo($li);
if ($list.parents(".inline").length) {
var $fileInput = $list.parents(".files-field").find("> input");
var val = $fileInput.val();
val = val ? val + "," + fileId : fileId;
$fileInput.val(val);
} else {
$('<input type="hidden" name="file[]">')
.attr('value', fileId)
.appendTo($li);
if ($list.data("adddescription")) {
$("<label>")
.addClass("col-form-label col-sm-4")
.text(tr("Description"))
.appendTo($li);
$("<div>").addClass("col-sm-12")
.append($('<textarea name="description[]">')
.addClass("form-control col-sm-8")
)
.appendTo($li);
}
}
};
};
handleFiles = function (input) {
var files = input.files,
accept = input.accept,
title = input.title,
galleryId = input.galleryId,
image_max_size_x = input.image_max_size_x,
image_max_size_y = input.image_max_size_y,
progressBar = input.progress,
ticket = input.ticket,
fileList = input.list,
$container = input.form, // sometimes a div when inline
$modal = $container.parents(".modal-dialog:first");
if (! $modal.length) {
$modal = $container;
}
var uploadUrl = $.service('file', 'upload');
var restoreExif = function(sourceImageData, newImageData){
if (sourceImageData.indexOf('data:image/jpeg;base64,') !== 0){
return newImageData;
}
var sourceImageSegments = MinifyJpeg.slice2Segments(MinifyJpeg.decode64(sourceImageData.replace("data:image/jpeg;base64,", "")));
var exifInfo = MinifyJpeg.getExif(sourceImageSegments);
var newImageBinArray = MinifyJpeg.insertExif(newImageData, exifInfo);
return "data:image/jpeg;base64," + MinifyJpeg.encode64(newImageBinArray);
};
$.each(files, function (k, file) {
var reader = new FileReader();
progressBar.updateSegment(k, 0, file.size);
window.lastFile = file;
$(window).queue('process-upload', function () {
reader.onloadend = function (e) {
var xhr, provider, sendData, data, valid = true;
$modal.tikiModal(tr("Uploading file..."));
xhr = jQuery.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
progressBar.updateSegment(k, e.loaded, e.total);
}
}, false);
}
provider = function () {
return xhr;
};
sendData = {
type: 'POST',
url: uploadUrl,
xhr: provider,
dataType: 'json',
global: false, // prevent ajaxError in tiki-jquery.js from closing the dialogs, leading to lost edits
success: function (data) {
fileList.addFile(data.fileId, file, title);
},
error: function (jqXHR, textStatus, errorThrown) {
progressBar.updateSegment(k, 0, 0);
fileList.addError(file, errorThrown);
},
complete: function (data, textStatus) {
$(window).dequeue('process-upload');
if (data.responseJSON) {
ticket = data.responseJSON.ticket;
// for modal
if ($modal !== $container) {
$('form.file-uploader-result input[name=ticket]').val(ticket);
}
// for both (form when in modal, div when inline)
$container.data('ticket', ticket);
} else {
alert(tr("There was an error: " + textStatus));
}
$modal.tikiModal();
}
};
if (window.FormData) {
sendData.processData = false;
sendData.contentType = false;
sendData.cache = false;
sendData.data = new FormData;
sendData.data.append('galleryId', galleryId);
sendData.data.append('image_max_size_x', image_max_size_x);
sendData.data.append('image_max_size_y', image_max_size_y);
sendData.data.append('ticket', ticket);
sendData.data.append('name', file.name);
sendData.data.append('title', title);
var waiting = false;
//checking if image is uploaded to call resize function and resizing options are set by tracker
// field creator
if (file.type.substring(0, 6) == 'image/' && (image_max_size_x || image_max_size_y)) {
waiting = true;
var imageData;
var picFile = e.target;
imageData = picFile.result;
var img = new Image();
var blobImage = null;
img.src = imageData;
img.onload = function () {
var width = parseInt(image_max_size_x);
var height = parseInt(image_max_size_y);
var image_x = parseInt(image_max_size_x);
var image_y = parseInt(image_max_size_y);
var ratio;
if (img.width > image_x || img.height > image_y) {
if (img.width > image_x) {
width = image_x;
ratio = image_x / img.width;
height = Math.round(img.height * ratio);
}
if (height > image_y) {
height = image_y;
ratio = image_y / img.height;
width = Math.round(img.width * ratio);
}
} else {
width = img.width;
height = img.height;
}
var canvas = $("<canvas/>").get(0);
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0, width, height);
var resizedImage = restoreExif(imageData, canvas.toDataURL('image/jpeg'));
blobImage = dataURItoBlob(resizedImage);
sendData.data.append('data', blobImage, file.name);
$.ajax(sendData);
}
} else {
sendData.data.append('data', file);
}
} else {
data = e.target.result;
sendData.data = {
name: file.name,
size: file.size,
type: file.type,
title: title,
data: data.substr(data.indexOf('base64') + 7),
galleryId: galleryId,
image_max_size_x: image_max_size_x,
image_max_size_y: image_max_size_y
};
}
if (accept) {
valid = file.type.match(new RegExp(".?(" + accept.replace('*', '.*') + ")$", "i"));
}
if (valid && !waiting) {
$.ajax(sendData);
} else {
if (!valid) {
sendData.error(null);
}
}
};
reader.readAsDataURL(file);
});
});
$(window).dequeue('process-upload');
};
$(document).on('submit', 'form.file-uploader', function (e) {
e.preventDefault();
});
function doUpload($form, files) {
var progress, list, title = "";
progress = new ProgressBar({
progress: function (current, total) {
var percentage = Math.round(current / total * 100);
$form.find('.progress').removeClass("invisible");
$form.find('.progress-bar')
.attr('aria-valuenow', percentage)
.width(percentage + '%');
$form.find('.progress-bar .sr-only .count')
.text(percentage);
},
done: function () {
$form.find('.progress').addClass("invisible");
$form.find('.progress-bar')
.attr('aria-valuenow', 0)
.width('0%');
$form.find('.progress-bar .sr-only .count')
.text('0%');
// Clear required title in preparation for next file
$('.custom-file-title-input', $form).val('');
}
});
list = new FileList({
list: $form.parent().find('.file-uploader-result ul')[0]
});
list.clearErrors();
if ($form.find('.custom-file-title-input').length) {
title = $form.find('.custom-file-title-input').val();
}
handleFiles({
accept: $form.find(':file').attr('accept'),
galleryId: $form.data('gallery-id'),
title: title,
ticket: $form.data('ticket'),
image_max_size_x:$form.data('image_max_size_x'),
image_max_size_y:$form.data('image_max_size_y'),
files: files,
progress: progress,
list: list,
form: $form
});
}
function validateTitleProvided(form) {
if ($('.custom-file-title', form).is(':visible')) {
if (!$('.custom-file-title-input', form).val()) {
$('.custom-file-title .feedback-required-title', form).show();
$('.custom-file-label', form).text('Choose file');
form.trigger('reset');
return false;
} else {
$('.custom-file-title .feedback-required-title', form).hide();
return true;
}
}
return true;
}
function validateOneAtTime(form, files) {
if ($('.custom-file-title', form).is(':visible')) {
if (files.length > 1) {
$('.custom-file-title .feedback-one-at-time', form).show();
$('.custom-file-label', form).text('Choose file');
form.trigger('reset');
return false;
} else {
$('.custom-file-title .feedback-one-at-time', form).hide();
return true;
}
}
return true;
}
$(document).on('change', '.file-uploader input[type=file]', function () {
var $clone, $form = $(this).closest("form"), progress, list;
if (this.files) {
if (!validateTitleProvided($form)) {
return false;
}
if (!validateOneAtTime($form, this.files)) {
return false;
}
let $inlineDiv = $(this).parents(".file-uploader.inline");
if ($inlineDiv.length) {
doUpload($inlineDiv, this.files);
} else {
doUpload($form, this.files);
}
$(this).val('');
$clone = $(this).clone(true);
$(this).replaceWith($clone);
}
});
if (window.FileReader) {
$(document).ready(function () {
$('.drop-message').show();
});
$(document).on('dragenter', '.file-uploader', function (e) {
e.preventDefault();
e.stopPropagation();
$(this).addClass("active");
return false;
});
$(document).on('dragexit dragleave', '.file-uploader', function (e) {
e.preventDefault();
e.stopPropagation();
$(this).removeClass("active");
return false;
});
$(document).on('dragover', '.file-uploader', function (e) {
e.preventDefault();
e.stopPropagation();
return false;
});
$(document).on('drop', '.file-uploader', function (e) {
var $form = $(this);
if (!validateTitleProvided($form)) {
return false;
}
e.preventDefault();
e.stopPropagation();
$(this).removeClass("active");
var dataTransfer = e.dataTransfer;
if (! dataTransfer) {
dataTransfer = e.originalEvent.dataTransfer;
}
if (dataTransfer && dataTransfer.files) {
if (!validateOneAtTime($form, dataTransfer.files)) {
return false;
}
doUpload($form, dataTransfer.files);
}
return false;
});
}
function browserRemoveFile(link)
{
var list = $(link).closest('ul');
$(link).closest('li').remove();
list.closest('.file-browser').trigger('selection-update');
}
function browserAddFile(link)
{
var content = $(link).closest('.media-body').clone(true),
icon = $(link).closest('.media, .panel').find('.media-object, .panel-body a').children('img').clone(true).width('16px'),
nav = $(link).closest('.file-browser').find('.selection ul'),
item = $('<li>'),
a = $('<a>').text($(link).text()),
id = $(link).data('object'),
limit = nav.closest('form').data('limit'),
current = nav.find('input[type=hidden]').filter(function () {
return parseInt($(this).val(), 10) === id;
});
if (current.length > 0) {
// Already in the list
browserRemoveFile(current[0]);
return;
}
if (limit === 1) {
nav.empty();
} else if (limit && nav.children('li').length >= limit) {
alert(nav.closest('form').data('limit-reached-message'));
return;
}
a
.prepend(' ')
.prepend(icon);
item.append(a);
nav.append(item);
item.append($('<input type="hidden" name="file[]">')
.attr('value', id));
nav.closest('.file-browser').trigger('selection-update');
}
$(document).on('selection-update', '.file-browser', function (e) {
var selection = $('.selection input[type=hidden]', this).map(function () {
return parseInt($(this).val(), 10);
});
$('.gallery-list .media-heading a, .gallery-list .panel-body a', this).each(function () {
var id = $(this).data('object');
$(this).closest('.media').toggleClass('bg-info', -1 !== $.inArray(id, selection));
$(this).closest('.panel').toggleClass('panel-info', -1 !== $.inArray(id, selection));
});
$('.selection', this).toggleClass("invisible", selection.length === 0);
});
$(document).on('click', '.file-browser .gallery-list .pagination a', function (e) {
e.preventDefault();
$(this).closest('.modal').animate({ scrollTop: 0 }, 'slow');
$(this).closest('.gallery-list')
.tikiModal(tr('Loading...'))
.load($(this).attr('href'), function () {
$(this).tikiModal('');
$(this).closest('.file-browser').trigger('selection-update');
});
});
$(document).on('click', '.file-browser .gallery-list .media-heading a, .file-browser .gallery-list .panel-body a', function (e) {
e.preventDefault();
e.stopPropagation();
browserAddFile(this);
});
$(document).on('click', '.file-browser .gallery-list .media, .file-browser .gallery-list .panel', function (e) {
e.preventDefault();
$('.media-heading a, .panel-body a', this).click();
});
$(document).on('click', '.file-browser .selection a', function (e) {
e.preventDefault();
browserRemoveFile(this);
});
$(document).on('submit', '.file-browser .form-inline', function (e) {
e.preventDefault();
$(this).closest('.file-browser').find('.gallery-list')
.tikiModal(tr('Loading...'))
.load($(this).attr('action'), $(this).serialize(), function () {
$(this).tikiModal('');
$(this).closest('.file-browser').trigger('selection-update');
});
});
$(document).on('click', '.file-browser .submit .upload-files', function (e) {
var $list = $(this).closest('.file-browser').find('.selection ul'),
handler = $.clickModal({
success: function (data) {
$.each(data.files, function (k, file) {
$('<li>')
.append($('<a href="#">')
.data('object', file.fileId)
.data('type', 'file')
.text(file.label))
.append($('<input type="hidden" name="file[]">')
.attr('value', file.fileId))
.appendTo($list);
$list.closest('.file-browser').trigger('selection-update');
});
$.closeModal();
}
});
handler.apply(this, arguments);
});
// File selector component
$(document).on('click', '.file-selector a', function () {
if (! $(this).data('initial-href')) {
$(this).data('initial-href', $(this).attr('href'));
}
// Before the dialog handler triggers, replace the href with one including current files
$(this).attr('href', $(this).data('initial-href') + '&file=' + $(this).parent().children('input').val());
});
$(document).on('click', '.file-selector a', $.clickModal({
size: 'modal-lg',
success: function (data) {
var files = [];
$.each(data.files, function (k, f) {
files.push(f.fileId);
});
$(this).parent().children('input').val(files.join(','));
$(this).text($(this).text().replace(/\d+/, files.length));
$.closeModal();
}
}));
})(jQuery);
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(dataURI.split(',')[1]);
} else {
byteString = unescape(dataURI.split(',')[1]);
}
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia],{ type:'image/jpeg' });
}
/* To minify a jpeg image without loosing EXIF.
* TESTED(24/01/2013): FireFox, GoogleChrome, IE10, Opera
* Copyright (c) 2013 hMatoba
* Released under the MIT license : https://github.com/hMatoba/MinifyJpegAsync/blob/master/LICENSE.txt
*
* To minify jpeg image:
* minified = MinifyJpeg.minify(image, length);
* xhr.send(minified.buffer);
* enc = "data:image/jpeg;base64," + MinifyJpeg.encode64(minified);
* html = '<img src="' + enc + '">';
* MinifyJpeg.minify() - return Uint8Array
* image - image base64encoded, it can be obtained "FileReader().readAsDataURL(f)"
* length - the long side length of the rectangle
* MinifyJpeg.encode64() - convert array to base64encoded string
*/
var MinifyJpeg = (function () {
var that = {};
that.KEY_STR = "ABCDEFGHIJKLMNOP" +
"QRSTUVWXYZabcdef" +
"ghijklmnopqrstuv" +
"wxyz0123456789+/" +
"=";
that.SOF = [192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207];
that.minify = function (image, new_size) {
var newImage, rawImage;
if (image instanceof ArrayBuffer) {
if (image[0] == 255 && image[1] == 216) {
rawImage = [];
for (var i = 0; i < image.byteLength; i++) {
rawImage[i] = image[i];
}
}
else {
throw "MinifyJpeg.minify got a not JPEG data";
}
}
else {
if (typeof(image) === "string") {
if (!image.match("data:image/jpeg;base64,")) {
throw "MinifyJpeg.minify got a not JPEG data";
}
else {
rawImage = that.decode64(image.replace("data:image/jpeg;base64,", ""));
}
}
else {
throw "First argument must be 'DataURL string' or ArrayBuffer.";
}
}
var segments = that.slice2Segments(rawImage);
var NEW_SIZE = parseInt(new_size);
var size = that.imageSizeFromSegments(segments);
var chouhen = (size[0] >= size[1]) ? size[0] : size[1];
if (chouhen < NEW_SIZE) {
return new Uint8Array(rawImage);
}
var exif = that.getExif(segments);
var resized = that.resizeImage(rawImage, segments, NEW_SIZE);
if (exif.length) {
newImage = that.insertExif(resized, exif);
}
else {
newImage = new Uint8Array(that.decode64(resized.replace("data:image/jpeg;base64,", "")));
}
return newImage;
};
that.getImageSize = function (imageArray) {
var segments = that.slice2Segments(imageArray);
return that.imageSizeFromSegments(segments);
};
that.slice2Segments = function (rawImageArray) {
var head = 0,
segments = [];
while (1) {
if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218) {
break;
}
if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216) {
head += 2;
}
else {
var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],
endPoint = head + length + 2,
seg = rawImageArray.slice(head, endPoint);
segments.push(seg);
head = endPoint;
}
if (head > rawImageArray.length) {
break;
}
}
return segments;
};
that.imageSizeFromSegments = function (segments) {
for (var x = 0; x < segments.length; x++) {
var seg = segments[x];
if (that.SOF.indexOf(seg[1]) >= 0) {
var height = seg[5] * 256 + seg[6],
width = seg[7] * 256 + seg[8];
break;
}
}
return [width, height];
};
that.encode64 = function (input) {
var output = "",
chr1, chr2, chr3 = "",
enc1, enc2, enc3, enc4 = "",
i = 0;
do {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else {
if (isNaN(chr3)) {
enc4 = 64;
}
}
output += that.KEY_STR.charAt(enc1) +
that.KEY_STR.charAt(enc2) +
that.KEY_STR.charAt(enc3) +
that.KEY_STR.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
};
that.decode64 = function (input) {
var chr1, chr2, chr3 = "",
enc1, enc2, enc3, enc4 = "",
i = 0,
buf = [];
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
alert("There were invalid base64 characters in the input text.\n" +
"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
"Expect errors in decoding.");
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = that.KEY_STR.indexOf(input.charAt(i++));
enc2 = that.KEY_STR.indexOf(input.charAt(i++));
enc3 = that.KEY_STR.indexOf(input.charAt(i++));
enc4 = that.KEY_STR.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
buf.push(chr1);
if (enc3 != 64) {
buf.push(chr2);
}
if (enc4 != 64) {
buf.push(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return buf;
};
that.resizeImage = function (rawImage, segments, NEW_SIZE) {
var jpe, ctx, srcImg;
var size = that.imageSizeFromSegments(segments),
width = size[0],
height = size[1],
chouhen = (width >= height) ? width : height,
newSize = NEW_SIZE,
resizing = 1,
scale = parseFloat(newSize) / chouhen,
newWidth = parseInt(parseFloat(newSize) / chouhen * width),
newHeight = parseInt(parseFloat(newSize) / chouhen * height);
if (resizing == 1) // bilinear
{
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
jpe = new JpegImage();
ctx = canvas.getContext("2d");
srcImg = ctx.getImageData(0, 0, width, height);
jpe.parse(new Uint8Array(rawImage));
jpe.copyToImageData(srcImg);
var newCanvas = document.createElement('canvas');
newCanvas.width = newWidth;
newCanvas.height = newHeight;
var newCtx = newCanvas.getContext("2d");
var destImg = newCtx.createImageData(newWidth, newHeight);
that.bilinear(srcImg, destImg, scale);
newCtx.putImageData(destImg, 0, 0);
var resizedImage = newCanvas.toDataURL("image/jpeg");
}
else // nearest neighbor?
{
canvas = document.createElement('canvas');
canvas.width = newWidth;
canvas.height = newHeight;
jpe = new JpegImage();
ctx = canvas.getContext("2d");
d = ctx.getImageData(0, 0, newWidth, newHeight);
jpe.parse(new Uint8Array(rawImage));
jpe.copyToImageData(d);
ctx.putImageData(d, 0, 0);
resizedImage = canvas.toDataURL("image/jpeg");
}
return resizedImage;
};
that.getExif = function (segments) {
var seg;
for (var x = 0; x < segments.length; x++) {
seg = segments[x];
if (seg[0] == 255 & seg[1] == 225) //(ff e1)
{
return seg;
}
}
return [];
};
that.insertExif = function (imageStr, exifArray) {
var buf = that.decode64(imageStr.replace("data:image/jpeg;base64,", "")),
separatePoint = buf.indexOf(255, 3),
mae = buf.slice(0, separatePoint),
ato = buf.slice(separatePoint),
array = mae.concat(exifArray, ato);
aBuffer = new Uint8Array(array);
return aBuffer;
};
// compute vector index from matrix one
that.ivect = function (ix, iy, w) {
// byte array, r,g,b,a
return ((ix + w * iy) * 4);
};
that.bilinear = function (srcImg, destImg, scale) {
// c.f.: wikipedia english article on bilinear interpolation
//log.debug("in bilinear");
// taking the unit square
function inner(f00, f10, f01, f11, x, y)
{
var un_x = 1.0 - x;
var un_y = 1.0 - y;
return (f00 * un_x * un_y + f10 * x * un_y + f01 * un_x * y + f11 * x * y);
}
var srcWidth = srcImg.width;
var srcHeight = srcImg.height;
var srcData = srcImg.data;
var dstData = destImg.data;
var i, j;
var iyv, iy0, iy1, ixv, ix0, ix1;
var idxD, idxS00, idxS10, idxS01, idxS11;
var dx, dy;
for (i = 0; i < destImg.height; ++i) {
iyv = (i + 0.5) / scale - 0.5;
iy0 = Math.floor(iyv);
iy1 = (Math.ceil(iyv) > (srcHeight - 1) ? (srcHeight - 1) : Math.ceil(iyv));
for (j = 0; j < destImg.width; ++j) {
ixv = (j + 0.5) / scale - 0.5;
ix0 = Math.floor(ixv);
ix1 = (Math.ceil(ixv) > (srcWidth - 1) ? (srcWidth - 1) : Math.ceil(ixv));
idxD = that.ivect(j, i, destImg.width);
idxS00 = that.ivect(ix0, iy0, srcWidth);
idxS10 = that.ivect(ix1, iy0, srcWidth);
idxS01 = that.ivect(ix0, iy1, srcWidth);
idxS11 = that.ivect(ix1, iy1, srcWidth);
// log.debug(sprintf("bilinear: idx: D: %d, S00: %d, S10: %d, S01: %d, S11: %d", idxD, idxS00, idxS10,
// idxS01, idxS11));
dx = ixv - ix0;
dy = iyv - iy0;
//r
dstData[idxD] = inner(srcData[idxS00], srcData[idxS10],
srcData[idxS01], srcData[idxS11], dx, dy
);
//g
dstData[idxD + 1] = inner(srcData[idxS00 + 1], srcData[idxS10 + 1],
srcData[idxS01 + 1], srcData[idxS11 + 1], dx, dy
);
//b
dstData[idxD + 2] = inner(srcData[idxS00 + 2], srcData[idxS10 + 2],
srcData[idxS01 + 2], srcData[idxS11 + 2], dx, dy
);
//a
dstData[idxD + 3] = inner(srcData[idxS00 + 3], srcData[idxS10 + 3],
srcData[idxS01 + 3], srcData[idxS11 + 3], dx, dy
);
}
}
};
return that;
})();
function processFgalSyntax(fileInfo, theSyntax) {
var key, part, syntax = "";
if (typeof fileInfo === "string") {
fileInfo = JSON.parse(fileInfo);
}
syntax = syntax ? decodeURIComponent(syntax[1]) : (theSyntax || fileInfo.syntax || fileInfo.wiki_syntax);
for (key in fileInfo) {
if (fileInfo.hasOwnProperty(key)) {
part = "{" + key + "}";
if (syntax.indexOf(part) > -1) {
syntax = syntax.replace(part, fileInfo[key]);
}
}
}
return syntax;
}