PHP Classes

File: uploady/assets/vendor/camansjs/dist/caman.js

Recommend this page to a friend!
  Classes of Faris AL-Otabi   Uploady PHP Upload File to MySQL   uploady/assets/vendor/camansjs/dist/caman.js   Download  
File: uploady/assets/vendor/camansjs/dist/caman.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Uploady PHP Upload File to MySQL
Store file upload details in a MySQL database
Author: By
Last change: update permission to 755
Date: 4 months ago
Size: 75,467 bytes
 

Contents

Class file image Download
// Generated by CoffeeScript 1.12.7 (function() { var $, Analyze, Blender, Calculate, Caman, CamanParser, Canvas, Convert, Event, Fiber, Filter, IO, Image, Layer, Log, Module, Pixel, Plugin, Renderer, Root, Store, Util, fs, http, moduleKeywords, slice, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, slice1 = [].slice, hasProp = {}.hasOwnProperty, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; moduleKeywords = ['extended', 'included']; Module = (function() { function Module() {} Module["extends"] = function(obj) { var key, ref, value; for (key in obj) { value = obj[key]; if (indexOf.call(moduleKeywords, key) < 0) { this[key] = value; } } if ((ref = obj.extended) != null) { ref.apply(this); } return this; }; Module.includes = function(obj) { var key, ref, value; for (key in obj) { value = obj[key]; if (indexOf.call(moduleKeywords, key) < 0) { this.prototype[key] = value; } } if ((ref = obj.included) != null) { ref.apply(this); } return this; }; Module.delegate = function() { var args, len, o, results, source, target; args = 1 <= arguments.length ? slice1.call(arguments, 0) : []; target = args.pop(); results = []; for (o = 0, len = args.length; o < len; o++) { source = args[o]; results.push(this.prototype[source] = target.prototype[source]); } return results; }; Module.aliasFunction = function(to, from) { return this.prototype[to] = (function(_this) { return function() { var args; args = 1 <= arguments.length ? slice1.call(arguments, 0) : []; return _this.prototype[from].apply(_this, args); }; })(this); }; Module.aliasProperty = function(to, from) { return Object.defineProperty(this.prototype, to, { get: function() { return this[from]; }, set: function(val) { return this[from] = val; } }); }; Module.included = function(func) { return func.call(this, this.prototype); }; return Module; })(); slice = Array.prototype.slice; $ = function(sel, root) { if (root == null) { root = document; } if (typeof sel === "object" || (typeof exports !== "undefined" && exports !== null)) { return sel; } return root.querySelector(sel); }; Util = (function() { function Util() {} Util.uniqid = (function() { var id; id = 0; return { get: function() { return id++; } }; })(); Util.extend = function() { var copy, dest, len, o, obj, prop, src; obj = arguments[0], src = 2 <= arguments.length ? slice1.call(arguments, 1) : []; dest = obj; for (o = 0, len = src.length; o < len; o++) { copy = src[o]; for (prop in copy) { if (!hasProp.call(copy, prop)) continue; dest[prop] = copy[prop]; } } return dest; }; Util.clampRGB = function(val) { if (val < 0) { return 0; } if (val > 255) { return 255; } return val; }; Util.copyAttributes = function(from, to, opts) { var attr, len, o, ref, ref1, results; if (opts == null) { opts = {}; } ref = from.attributes; results = []; for (o = 0, len = ref.length; o < len; o++) { attr = ref[o]; if ((opts.except != null) && (ref1 = attr.nodeName, indexOf.call(opts.except, ref1) >= 0)) { continue; } results.push(to.setAttribute(attr.nodeName, attr.nodeValue)); } return results; }; Util.dataArray = function(length) { if (length == null) { length = 0; } if (Caman.NodeJS || (window.Uint8Array != null)) { return new Uint8Array(length); } return new Array(length); }; return Util; })(); if (typeof exports !== "undefined" && exports !== null) { Root = exports; Canvas = require('canvas'); Image = Canvas.Image; Fiber = require('fibers'); fs = require('fs'); http = require('http'); } else { Root = window; } Caman = (function(superClass) { extend(Caman, superClass); Caman.version = { release: "4.1.2", date: "7/27/2013" }; Caman.DEBUG = false; Caman.allowRevert = true; Caman.crossOrigin = "anonymous"; Caman.remoteProxy = ""; Caman.proxyParam = "camanProxyUrl"; Caman.NodeJS = typeof exports !== "undefined" && exports !== null; Caman.autoload = !Caman.NodeJS; Caman.toString = function() { return "Version " + Caman.version.release + ", Released " + Caman.version.date; }; Caman.getAttrId = function(canvas) { if (Caman.NodeJS) { return true; } if (typeof canvas === "string") { canvas = $(canvas); } if (!((canvas != null) && (canvas.getAttribute != null))) { return null; } return canvas.getAttribute('data-caman-id'); }; function Caman() { this.nodeFileReady = bind(this.nodeFileReady, this); var args, callback, id; if (arguments.length === 0) { throw "Invalid arguments"; } if (this instanceof Caman) { this.finishInit = this.finishInit.bind(this); this.imageLoaded = this.imageLoaded.bind(this); args = arguments[0]; if (!Caman.NodeJS) { id = parseInt(Caman.getAttrId(args[0]), 10); callback = typeof args[1] === "function" ? args[1] : typeof args[2] === "function" ? args[2] : function() {}; if (!isNaN(id) && Store.has(id)) { return Store.execute(id, callback); } } this.id = Util.uniqid.get(); this.initializedPixelData = this.originalPixelData = null; this.cropCoordinates = { x: 0, y: 0 }; this.cropped = false; this.resized = false; this.rotated = false; this.rotationAngle = 0; this.pixelStack = []; this.layerStack = []; this.canvasQueue = []; this.currentLayer = null; this.scaled = false; this.analyze = new Analyze(this); this.renderer = new Renderer(this); this.domIsLoaded((function(_this) { return function() { _this.parseArguments(args); return _this.setup(); }; })(this)); return this; } else { return new Caman(arguments); } } Caman.prototype.domIsLoaded = function(cb) { var listener; if (Caman.NodeJS) { return setTimeout((function(_this) { return function() { return cb.call(_this); }; })(this), 0); } else { if (document.readyState === "complete") { Log.debug("DOM initialized"); return setTimeout((function(_this) { return function() { return cb.call(_this); }; })(this), 0); } else { listener = (function(_this) { return function() { if (document.readyState === "complete") { Log.debug("DOM initialized"); return cb.call(_this); } }; })(this); return document.addEventListener("readystatechange", listener, false); } } }; Caman.prototype.parseArguments = function(args) { var key, ref, results, val; if (args.length === 0) { throw "Invalid arguments given"; } this.initObj = null; this.initType = null; this.imageUrl = null; this.callback = function() {}; this.setInitObject(args[0]); if (args.length === 1) { return; } switch (typeof args[1]) { case "string": this.imageUrl = args[1]; break; case "function": this.callback = args[1]; } if (args.length === 2) { return; } this.callback = args[2]; if (args.length === 4) { ref = args[4]; results = []; for (key in ref) { if (!hasProp.call(ref, key)) continue; val = ref[key]; results.push(this.options[key] = val); } return results; } }; Caman.prototype.setInitObject = function(obj) { if (Caman.NodeJS) { this.initObj = obj; this.initType = 'node'; return; } if (typeof obj === "object") { this.initObj = obj; } else { this.initObj = $(obj); } if (this.initObj == null) { throw "Could not find image or canvas for initialization."; } return this.initType = this.initObj.nodeName.toLowerCase(); }; Caman.prototype.setup = function() { switch (this.initType) { case "node": return this.initNode(); case "img": return this.initImage(); case "canvas": return this.initCanvas(); } }; Caman.prototype.initNode = function() { Log.debug("Initializing for NodeJS"); if (typeof this.initObj === "string" && this.initObj.match(/^https?:\/\//)) { return this.readFromHttp(this.initObj, this.nodeFileReady); } else if (typeof this.initObj === "string") { return fs.readFile(this.initObj, this.nodeFileReady); } else { return this.nodeFileReady(null, this.initObj); } }; Caman.prototype.readFromHttp = function(url, callback) { var req; Log.debug("Fetching image from " + url); req = http.get(url, function(res) { var buf; buf = ''; res.setEncoding('binary'); res.on('data', function(chunk) { return buf += chunk; }); return res.on('end', function() { return callback(null, new Buffer(buf, 'binary')); }); }); return req.on('error', callback); }; Caman.prototype.nodeFileReady = function(err, data) { if (err) { throw err; } this.image = new Image(); this.image.src = data; Log.debug("Image loaded. Width = " + (this.imageWidth()) + ", Height = " + (this.imageHeight())); this.canvas = new Canvas(this.imageWidth(), this.imageHeight()); this.renderingCanvas = new Canvas(this.imageWidth(), this.imageHeight()); return this.finishInit(); }; Caman.prototype.initImage = function() { this.image = this.initObj; this.canvas = document.createElement('canvas'); this.context = this.canvas.getContext('2d'); this.renderingCanvas = document.createElement('canvas'); this.renderingContext = this.renderingCanvas.getContext('2d'); Util.copyAttributes(this.image, this.canvas, { except: ['src'] }); Util.copyAttributes(this.image, this.renderingCanvas, { except: ['src'] }); if (this.image.parentNode != null) { this.image.parentNode.replaceChild(this.renderingCanvas, this.image); } this.imageAdjustments(); return this.waitForImageLoaded(); }; Caman.prototype.initCanvas = function() { this.canvas = document.createElement('canvas'); this.context = this.canvas.getContext('2d'); this.renderingCanvas = this.initObj; this.renderingContext = this.renderingCanvas.getContext('2d'); this.canvas.width = this.renderingCanvas.width; this.canvas.height = this.renderingCanvas.height; if (this.imageUrl != null) { this.image = document.createElement('img'); this.image.crossOrigin = 'anonymous'; this.image.src = this.imageUrl; this.imageAdjustments(); return this.waitForImageLoaded(); } else { return this.finishInit(); } }; Caman.prototype.imageAdjustments = function() { if (this.needsHiDPISwap()) { Log.debug(this.image.src, "->", this.hiDPIReplacement()); this.swapped = true; this.image.src = this.hiDPIReplacement(); } if (IO.isRemote(this.image)) { this.image.src = IO.proxyUrl(this.image.src); return Log.debug("Remote image detected, using URL = " + this.image.src); } }; Caman.prototype.waitForImageLoaded = function() { if (this.isImageLoaded()) { return this.imageLoaded(); } else { return this.image.onload = this.imageLoaded; } }; Caman.prototype.isImageLoaded = function() { if (!this.image.complete) { return false; } if ((this.image.naturalWidth != null) && this.image.naturalWidth === 0) { return false; } return true; }; Caman.prototype.imageWidth = function() { return this.image.width || this.image.naturalWidth; }; Caman.prototype.imageHeight = function() { return this.image.height || this.image.naturalHeight; }; Caman.prototype.imageLoaded = function() { Log.debug("Image loaded. Width = " + (this.imageWidth()) + ", Height = " + (this.imageHeight())); if (this.swapped) { this.canvas.width = this.imageWidth() / this.hiDPIRatio(); this.canvas.height = this.imageHeight() / this.hiDPIRatio(); this.renderingCanvas.width = this.imageWidth() / this.hiDPIRatio(); this.renderingCanvas.height = this.imageHeight() / this.hiDPIRatio(); } else { this.canvas.width = this.imageWidth(); this.canvas.height = this.imageHeight(); this.renderingCanvas.width = this.imageWidth(); this.renderingCanvas.height = this.imageHeight(); } return this.finishInit(); }; Caman.prototype.finishInit = function() { var i, len, o, pixel, ref; if (this.context == null) { this.context = this.canvas.getContext('2d'); } if (this.renderingContext == null) { this.renderingContext = this.renderingCanvas.getContext('2d'); } this.originalWidth = this.preScaledWidth = this.width = this.canvas.width; this.originalHeight = this.preScaledHeight = this.height = this.canvas.height; this.hiDPIAdjustments(); if (!this.hasId()) { this.assignId(); } if (this.image != null) { this.context.drawImage(this.image, 0, 0, this.imageWidth(), this.imageHeight(), 0, 0, this.preScaledWidth, this.preScaledHeight); this.renderingContext.drawImage(this.image, 0, 0, this.imageWidth(), this.imageHeight(), 0, 0, this.preScaledWidth, this.preScaledHeight); } this.imageData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); this.pixelData = this.imageData.data; if (Caman.allowRevert) { this.initializedPixelData = Util.dataArray(this.pixelData.length); this.originalPixelData = Util.dataArray(this.pixelData.length); ref = this.pixelData; for (i = o = 0, len = ref.length; o < len; i = ++o) { pixel = ref[i]; this.initializedPixelData[i] = pixel; this.originalPixelData[i] = pixel; } } this.dimensions = { width: this.canvas.width, height: this.canvas.height }; if (!Caman.NodeJS) { Store.put(this.id, this); } this.callback.call(this, this); return this.callback = function() {}; }; Caman.prototype.reloadCanvasData = function() { this.imageData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); return this.pixelData = this.imageData.data; }; Caman.prototype.resetOriginalPixelData = function() { var i, len, o, pixel, ref, results; if (!Caman.allowRevert) { throw "Revert disabled"; } this.originalPixelData = Util.dataArray(this.pixelData.length); ref = this.pixelData; results = []; for (i = o = 0, len = ref.length; o < len; i = ++o) { pixel = ref[i]; results.push(this.originalPixelData[i] = pixel); } return results; }; Caman.prototype.hasId = function() { return Caman.getAttrId(this.canvas) != null; }; Caman.prototype.assignId = function() { if (Caman.NodeJS || this.canvas.getAttribute('data-caman-id')) { return; } return this.canvas.setAttribute('data-caman-id', this.id); }; Caman.prototype.hiDPIDisabled = function() { return this.canvas.getAttribute('data-caman-hidpi-disabled') !== null; }; Caman.prototype.hiDPIAdjustments = function() { var ratio; if (Caman.NodeJS || !this.needsHiDPISwap()) { return; } ratio = this.hiDPIRatio(); if (ratio !== 1) { Log.debug("HiDPI ratio = " + ratio); this.scaled = true; this.preScaledWidth = this.canvas.width; this.preScaledHeight = this.canvas.height; this.canvas.width = this.preScaledWidth * ratio; this.canvas.height = this.preScaledHeight * ratio; this.canvas.style.width = this.preScaledWidth + "px"; this.canvas.style.height = this.preScaledHeight + "px"; this.context.scale(ratio, ratio); this.width = this.originalWidth = this.canvas.width; return this.height = this.originalHeight = this.canvas.height; } }; Caman.prototype.hiDPIRatio = function() { var backingStoreRatio, devicePixelRatio; devicePixelRatio = window.devicePixelRatio || 1; backingStoreRatio = this.context.webkitBackingStorePixelRatio || this.context.mozBackingStorePixelRatio || this.context.msBackingStorePixelRatio || this.context.oBackingStorePixelRatio || this.context.backingStorePixelRatio || 1; return devicePixelRatio / backingStoreRatio; }; Caman.prototype.hiDPICapable = function() { return (window.devicePixelRatio != null) && window.devicePixelRatio !== 1; }; Caman.prototype.needsHiDPISwap = function() { if (this.hiDPIDisabled() || !this.hiDPICapable()) { return false; } return this.hiDPIReplacement() !== null; }; Caman.prototype.hiDPIReplacement = function() { if (this.image == null) { return null; } return this.image.getAttribute('data-caman-hidpi'); }; Caman.prototype.replaceCanvas = function(newCanvas) { var i, len, o, pixel, ref; this.canvas = newCanvas; this.context = this.canvas.getContext('2d'); this.imageData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); this.pixelData = this.imageData.data; if (Caman.allowRevert) { this.originalPixelData = Util.dataArray(this.pixelData.length); ref = this.pixelData; for (i = o = 0, len = ref.length; o < len; i = ++o) { pixel = ref[i]; this.originalPixelData[i] = pixel; } } this.width = this.canvas.width; this.height = this.canvas.height; this.reloadCanvasData(); return this.dimensions = { width: this.canvas.width, height: this.canvas.height }; }; Caman.prototype.render = function(callback) { if (callback == null) { callback = function() {}; } Event.trigger(this, "renderStart"); return this.renderer.execute((function(_this) { return function() { _this.renderingCanvas.width = _this.canvas.width; _this.renderingCanvas.height = _this.canvas.height; _this.renderingContext.putImageData(_this.imageData, 0, 0); return callback.call(_this); }; })(this)); }; Caman.prototype.revert = function(updateContext) { var i, len, o, pixel, ref; if (updateContext == null) { updateContext = true; } if (!Caman.allowRevert) { throw "Revert disabled"; } ref = this.originalVisiblePixels(); for (i = o = 0, len = ref.length; o < len; i = ++o) { pixel = ref[i]; this.pixelData[i] = pixel; } if (updateContext) { return this.renderingContext.putImageData(this.imageData, 0, 0); } }; Caman.prototype.reset = function() { var canvas, ctx, i, imageData, len, o, pixel, pixelData, ref; canvas = document.createElement('canvas'); Util.copyAttributes(this.canvas, canvas); canvas.width = this.originalWidth; canvas.height = this.originalHeight; ctx = canvas.getContext('2d'); imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); pixelData = imageData.data; ref = this.initializedPixelData; for (i = o = 0, len = ref.length; o < len; i = ++o) { pixel = ref[i]; pixelData[i] = pixel; } ctx.putImageData(imageData, 0, 0); this.cropCoordinates = { x: 0, y: 0 }; this.resized = false; return this.replaceCanvas(canvas); }; Caman.prototype.originalVisiblePixels = function() { var coord, endX, endY, i, o, pixelData, pixels, ref, ref1, ref2, startX, startY, width; if (!Caman.allowRevert) { throw "Revert disabled"; } pixels = []; startX = 0; endX = startX + this.width; startY = 0; endY = startY + this.height; pixelData = this.originalPixelData; width = this.canvas.width; for (i = o = 0, ref = pixelData.length; o < ref; i = o += 4) { coord = Pixel.locationToCoordinates(i, width); if (((startX <= (ref1 = coord.x) && ref1 < endX)) && ((startY <= (ref2 = coord.y) && ref2 < endY))) { pixels.push(pixelData[i], pixelData[i + 1], pixelData[i + 2], pixelData[i + 3]); } } return pixels; }; Caman.prototype.process = function(name, processFn) { this.renderer.add({ type: Filter.Type.Single, name: name, processFn: processFn }); return this; }; Caman.prototype.processKernel = function(name, adjust, divisor, bias) { var i, o, ref; if (divisor == null) { divisor = null; } if (bias == null) { bias = 0; } if (divisor == null) { divisor = 0; for (i = o = 0, ref = adjust.length; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { divisor += adjust[i]; } } this.renderer.add({ type: Filter.Type.Kernel, name: name, adjust: adjust, divisor: divisor, bias: bias }); return this; }; Caman.prototype.processPlugin = function(plugin, args) { this.renderer.add({ type: Filter.Type.Plugin, plugin: plugin, args: args }); return this; }; Caman.prototype.newLayer = function(callback) { var layer; layer = new Layer(this); this.canvasQueue.push(layer); this.renderer.add({ type: Filter.Type.LayerDequeue }); callback.call(layer); this.renderer.add({ type: Filter.Type.LayerFinished }); return this; }; Caman.prototype.executeLayer = function(layer) { return this.pushContext(layer); }; Caman.prototype.pushContext = function(layer) { this.layerStack.push(this.currentLayer); this.pixelStack.push(this.pixelData); this.currentLayer = layer; return this.pixelData = layer.pixelData; }; Caman.prototype.popContext = function() { this.pixelData = this.pixelStack.pop(); return this.currentLayer = this.layerStack.pop(); }; Caman.prototype.applyCurrentLayer = function() { return this.currentLayer.applyToParent(); }; return Caman; })(Module); Root.Caman = Caman; Caman.Analyze = (function() { function Analyze(c1) { this.c = c1; } Analyze.prototype.calculateLevels = function() { var i, levels, numPixels, o, ref, u, w; levels = { r: {}, g: {}, b: {} }; for (i = o = 0; o <= 255; i = ++o) { levels.r[i] = 0; levels.g[i] = 0; levels.b[i] = 0; } for (i = u = 0, ref = this.c.pixelData.length; u < ref; i = u += 4) { levels.r[this.c.pixelData[i]]++; levels.g[this.c.pixelData[i + 1]]++; levels.b[this.c.pixelData[i + 2]]++; } numPixels = this.c.pixelData.length / 4; for (i = w = 0; w <= 255; i = ++w) { levels.r[i] /= numPixels; levels.g[i] /= numPixels; levels.b[i] /= numPixels; } return levels; }; return Analyze; })(); Analyze = Caman.Analyze; Caman.DOMUpdated = function() { var img, imgs, len, o, parser, results; imgs = document.querySelectorAll("img[data-caman]"); if (!(imgs.length > 0)) { return; } results = []; for (o = 0, len = imgs.length; o < len; o++) { img = imgs[o]; results.push(parser = new CamanParser(img, function() { this.parse(); return this.execute(); })); } return results; }; if (Caman.autoload) { (function() { if (document.readyState === "complete") { return Caman.DOMUpdated(); } else { return document.addEventListener("DOMContentLoaded", Caman.DOMUpdated, false); } })(); } CamanParser = (function() { var INST_REGEX; INST_REGEX = "(\\w+)\\((.*?)\\)"; function CamanParser(ele, ready) { this.dataStr = ele.getAttribute('data-caman'); this.caman = Caman(ele, ready.bind(this)); } CamanParser.prototype.parse = function() { var args, e, filter, func, inst, instFunc, len, m, o, r, ref, results, unparsedInstructions; this.ele = this.caman.canvas; r = new RegExp(INST_REGEX, 'g'); unparsedInstructions = this.dataStr.match(r); if (!(unparsedInstructions.length > 0)) { return; } r = new RegExp(INST_REGEX); results = []; for (o = 0, len = unparsedInstructions.length; o < len; o++) { inst = unparsedInstructions[o]; ref = inst.match(r), m = ref[0], filter = ref[1], args = ref[2]; instFunc = new Function("return function() { this." + filter + "(" + args + "); };"); try { func = instFunc(); results.push(func.call(this.caman)); } catch (error) { e = error; results.push(Log.debug(e)); } } return results; }; CamanParser.prototype.execute = function() { var ele; ele = this.ele; return this.caman.render(function() { return ele.parentNode.replaceChild(this.toImage(), ele); }); }; return CamanParser; })(); Caman.Blender = (function() { function Blender() {} Blender.blenders = {}; Blender.register = function(name, func) { return this.blenders[name] = func; }; Blender.execute = function(name, rgbaLayer, rgbaParent) { return this.blenders[name](rgbaLayer, rgbaParent); }; return Blender; })(); Blender = Caman.Blender; Caman.Calculate = (function() { function Calculate() {} Calculate.distance = function(x1, y1, x2, y2) { return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); }; Calculate.randomRange = function(min, max, getFloat) { var rand; if (getFloat == null) { getFloat = false; } rand = min + (Math.random() * (max - min)); if (getFloat) { return rand.toFixed(getFloat); } else { return Math.round(rand); } }; Calculate.luminance = function(rgba) { return (0.299 * rgba.r) + (0.587 * rgba.g) + (0.114 * rgba.b); }; Calculate.bezier = function(start, ctrl1, ctrl2, end, lowBound, highBound) { var bezier, clamp, controlPoints, endX, i, j, lerp, next, o, prev, ref, t, u; if (lowBound == null) { lowBound = 0; } if (highBound == null) { highBound = 255; } if (start[0] instanceof Array) { controlPoints = start; lowBound = ctrl1; highBound = ctrl2; } else { controlPoints = [start, ctrl1, ctrl2, end]; } if (controlPoints.length < 2) { throw "Invalid number of arguments to bezier"; } bezier = {}; lerp = function(a, b, t) { return a * (1 - t) + b * t; }; clamp = function(a, min, max) { return Math.min(Math.max(a, min), max); }; for (i = o = 0; o < 1000; i = ++o) { t = i / 1000; prev = controlPoints; while (prev.length > 1) { next = []; for (j = u = 0, ref = prev.length - 2; 0 <= ref ? u <= ref : u >= ref; j = 0 <= ref ? ++u : --u) { next.push([lerp(prev[j][0], prev[j + 1][0], t), lerp(prev[j][1], prev[j + 1][1], t)]); } prev = next; } bezier[Math.round(prev[0][0])] = Math.round(clamp(prev[0][1], lowBound, highBound)); } endX = controlPoints[controlPoints.length - 1][0]; bezier = Caman.Calculate.missingValues(bezier, endX); if (bezier[endX] == null) { bezier[endX] = bezier[endX - 1]; } return bezier; }; Calculate.hermite = function(controlPoints, lowBound, highBound) { var add, clamp, count, endX, fac0, fac1, fac2, fac3, i, j, lerp, m0, m1, mul, o, p, p0, p1, pointsPerSegment, pointsPerStep, pos, ref, ref1, ret, sub, t, u; if (controlPoints.length < 2) { throw "Invalid number of arguments to hermite"; } ret = {}; lerp = function(a, b, t) { return a * (1 - t) + b * t; }; add = (function(_this) { return function(a, b, c, d) { return [a[0] + b[0] + c[0] + d[0], a[1] + b[1] + c[1] + d[1]]; }; })(this); mul = (function(_this) { return function(a, b) { return [a[0] * b[0], a[1] * b[1]]; }; })(this); sub = (function(_this) { return function(a, b) { return [a[0] - b[0], a[1] - b[1]]; }; })(this); clamp = function(a, min, max) { return Math.min(Math.max(a, min), max); }; count = 0; for (i = o = 0, ref = controlPoints.length - 2; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) { p0 = controlPoints[i]; p1 = controlPoints[i + 1]; pointsPerSegment = p1[0] - p0[0]; pointsPerStep = 1 / pointsPerSegment; if (i === controlPoints.length - 2) { pointsPerStep = 1 / (pointsPerSegment - 1); } p = i > 0 ? controlPoints[i - 1] : p0; m0 = mul(sub(p1, p), [0.5, 0.5]); p = i < controlPoints.length - 2 ? controlPoints[i + 2] : p1; m1 = mul(sub(p, p0), [0.5, 0.5]); for (j = u = 0, ref1 = pointsPerSegment; 0 <= ref1 ? u <= ref1 : u >= ref1; j = 0 <= ref1 ? ++u : --u) { t = j * pointsPerStep; fac0 = 2.0 * t * t * t - 3.0 * t * t + 1.0; fac1 = t * t * t - 2.0 * t * t + t; fac2 = -2.0 * t * t * t + 3.0 * t * t; fac3 = t * t * t - t * t; pos = add(mul(p0, [fac0, fac0]), mul(m0, [fac1, fac1]), mul(p1, [fac2, fac2]), mul(m1, [fac3, fac3])); ret[Math.round(pos[0])] = Math.round(clamp(pos[1], lowBound, highBound)); count += 1; } } endX = controlPoints[controlPoints.length - 1][0]; ret = Caman.Calculate.missingValues(ret, endX); return ret; }; Calculate.missingValues = function(values, endX) { var i, j, leftCoord, o, ref, ref1, ref2, ret, rightCoord, u; if (Object.keys(values).length < endX + 1) { ret = {}; for (i = o = 0, ref = endX; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) { if (values[i] != null) { ret[i] = values[i]; } else { leftCoord = [i - 1, ret[i - 1]]; for (j = u = ref1 = i, ref2 = endX; ref1 <= ref2 ? u <= ref2 : u >= ref2; j = ref1 <= ref2 ? ++u : --u) { if (values[j] != null) { rightCoord = [j, values[j]]; break; } } if (rightCoord) { ret[i] = leftCoord[1] + ((rightCoord[1] - leftCoord[1]) / (rightCoord[0] - leftCoord[0])) * (i - leftCoord[0]); } } } return ret; } return values; }; return Calculate; })(); Calculate = Caman.Calculate; Caman.Convert = (function() { function Convert() {} Convert.hexToRGB = function(hex) { var b, g, r; if (hex.charAt(0) === "#") { hex = hex.substr(1); } r = parseInt(hex.substr(0, 2), 16); g = parseInt(hex.substr(2, 2), 16); b = parseInt(hex.substr(4, 2), 16); return { r: r, g: g, b: b }; }; Convert.rgbToHSL = function(r, g, b) { var d, h, l, max, min, s; if (typeof r === "object") { g = r.g; b = r.b; r = r.r; } r /= 255; g /= 255; b /= 255; max = Math.max(r, g, b); min = Math.min(r, g, b); l = (max + min) / 2; if (max === min) { h = s = 0; } else { d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); h = (function() { switch (max) { case r: return (g - b) / d + (g < b ? 6 : 0); case g: return (b - r) / d + 2; case b: return (r - g) / d + 4; } })(); h /= 6; } return { h: h, s: s, l: l }; }; Convert.hslToRGB = function(h, s, l) { var b, g, p, q, r; if (typeof h === "object") { s = h.s; l = h.l; h = h.h; } if (s === 0) { r = g = b = l; } else { q = l < 0.5 ? l * (1 + s) : l + s - l * s; p = 2 * l - q; r = this.hueToRGB(p, q, h + 1 / 3); g = this.hueToRGB(p, q, h); b = this.hueToRGB(p, q, h - 1 / 3); } return { r: r * 255, g: g * 255, b: b * 255 }; }; Convert.hueToRGB = function(p, q, t) { if (t < 0) { t += 1; } if (t > 1) { t -= 1; } if (t < 1 / 6) { return p + (q - p) * 6 * t; } if (t < 1 / 2) { return q; } if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; } return p; }; Convert.rgbToHSV = function(r, g, b) { var d, h, max, min, s, v; r /= 255; g /= 255; b /= 255; max = Math.max(r, g, b); min = Math.min(r, g, b); v = max; d = max - min; s = max === 0 ? 0 : d / max; if (max === min) { h = 0; } else { h = (function() { switch (max) { case r: return (g - b) / d + (g < b ? 6 : 0); case g: return (b - r) / d + 2; case b: return (r - g) / d + 4; } })(); h /= 6; } return { h: h, s: s, v: v }; }; Convert.hsvToRGB = function(h, s, v) { var b, f, g, i, p, q, r, t; i = Math.floor(h * 6); f = h * 6 - i; p = v * (1 - s); q = v * (1 - f * s); t = v * (1 - (1 - f) * s); switch (i % 6) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; } return { r: Math.floor(r * 255), g: Math.floor(g * 255), b: Math.floor(b * 255) }; }; Convert.rgbToXYZ = function(r, g, b) { var x, y, z; r /= 255; g /= 255; b /= 255; if (r > 0.04045) { r = Math.pow((r + 0.055) / 1.055, 2.4); } else { r /= 12.92; } if (g > 0.04045) { g = Math.pow((g + 0.055) / 1.055, 2.4); } else { g /= 12.92; } if (b > 0.04045) { b = Math.pow((b + 0.055) / 1.055, 2.4); } else { b /= 12.92; } x = r * 0.4124 + g * 0.3576 + b * 0.1805; y = r * 0.2126 + g * 0.7152 + b * 0.0722; z = r * 0.0193 + g * 0.1192 + b * 0.9505; return { x: x * 100, y: y * 100, z: z * 100 }; }; Convert.xyzToRGB = function(x, y, z) { var b, g, r; x /= 100; y /= 100; z /= 100; r = (3.2406 * x) + (-1.5372 * y) + (-0.4986 * z); g = (-0.9689 * x) + (1.8758 * y) + (0.0415 * z); b = (0.0557 * x) + (-0.2040 * y) + (1.0570 * z); if (r > 0.0031308) { r = (1.055 * Math.pow(r, 0.4166666667)) - 0.055; } else { r *= 12.92; } if (g > 0.0031308) { g = (1.055 * Math.pow(g, 0.4166666667)) - 0.055; } else { g *= 12.92; } if (b > 0.0031308) { b = (1.055 * Math.pow(b, 0.4166666667)) - 0.055; } else { b *= 12.92; } return { r: r * 255, g: g * 255, b: b * 255 }; }; Convert.xyzToLab = function(x, y, z) { var a, b, l, whiteX, whiteY, whiteZ; if (typeof x === "object") { y = x.y; z = x.z; x = x.x; } whiteX = 95.047; whiteY = 100.0; whiteZ = 108.883; x /= whiteX; y /= whiteY; z /= whiteZ; if (x > 0.008856451679) { x = Math.pow(x, 0.3333333333); } else { x = (7.787037037 * x) + 0.1379310345; } if (y > 0.008856451679) { y = Math.pow(y, 0.3333333333); } else { y = (7.787037037 * y) + 0.1379310345; } if (z > 0.008856451679) { z = Math.pow(z, 0.3333333333); } else { z = (7.787037037 * z) + 0.1379310345; } l = 116 * y - 16; a = 500 * (x - y); b = 200 * (y - z); return { l: l, a: a, b: b }; }; Convert.labToXYZ = function(l, a, b) { var x, y, z; if (typeof l === "object") { a = l.a; b = l.b; l = l.l; } y = (l + 16) / 116; x = y + (a / 500); z = y - (b / 200); if (x > 0.2068965517) { x = x * x * x; } else { x = 0.1284185493 * (x - 0.1379310345); } if (y > 0.2068965517) { y = y * y * y; } else { y = 0.1284185493 * (y - 0.1379310345); } if (z > 0.2068965517) { z = z * z * z; } else { z = 0.1284185493 * (z - 0.1379310345); } return { x: x * 95.047, y: y * 100.0, z: z * 108.883 }; }; Convert.rgbToLab = function(r, g, b) { var xyz; if (typeof r === "object") { g = r.g; b = r.b; r = r.r; } xyz = this.rgbToXYZ(r, g, b); return this.xyzToLab(xyz); }; Convert.labToRGB = function(l, a, b) {}; return Convert; })(); Convert = Caman.Convert; Caman.Event = (function() { function Event() {} Event.events = {}; Event.types = ["processStart", "processComplete", "renderStart", "renderFinished", "blockStarted", "blockFinished"]; Event.trigger = function(target, type, data) { var event, len, o, ref, results; if (data == null) { data = null; } if (this.events[type] && this.events[type].length) { ref = this.events[type]; results = []; for (o = 0, len = ref.length; o < len; o++) { event = ref[o]; if (event.target === null || target.id === event.target.id) { results.push(event.fn.call(target, data)); } else { results.push(void 0); } } return results; } }; Event.listen = function(target, type, fn) { var _fn, _type; if (typeof target === "string") { _type = target; _fn = type; target = null; type = _type; fn = _fn; } if (indexOf.call(this.types, type) < 0) { return false; } if (!this.events[type]) { this.events[type] = []; } this.events[type].push({ target: target, fn: fn }); return true; }; return Event; })(); Event = Caman.Event; Caman.Filter = (function() { function Filter() {} Filter.Type = { Single: 1, Kernel: 2, LayerDequeue: 3, LayerFinished: 4, LoadOverlay: 5, Plugin: 6 }; Filter.register = function(name, filterFunc) { return Caman.prototype[name] = filterFunc; }; return Filter; })(); Filter = Caman.Filter; Caman.IO = (function() { function IO() {} IO.domainRegex = /(?:(?:http|https):\/\/)((?:[-|\w]+)\.(?:(?:-|\w|\.)+))/; IO.isRemote = function(img) { if (img == null) { return false; } if (this.corsEnabled(img)) { return false; } return this.isURLRemote(img.src); }; IO.corsEnabled = function(img) { return true; }; IO.isURLRemote = function(url) { var matches; matches = url.match(this.domainRegex); if (matches) { return matches[1] !== document.domain; } else { return false; } }; IO.remoteCheck = function(src) { if (this.isURLRemote(src)) { if (!Caman.remoteProxy.length) { Log.info("Attempting to load a remote image without a configured proxy. URL: " + src); } else { if (Caman.isURLRemote(Caman.remoteProxy)) { Log.info("Cannot use a remote proxy for loading images."); return; } return this.proxyUrl(src); } } }; IO.proxyUrl = function(src) { return Caman.remoteProxy + "?" + Caman.proxyParam + "=" + (encodeURIComponent(src)); }; IO.useProxy = function(lang) { var langToExt; langToExt = { ruby: 'rb', python: 'py', perl: 'pl', javascript: 'js' }; lang = lang.toLowerCase(); if (langToExt[lang] != null) { lang = langToExt[lang]; } return "proxies/caman_proxy." + lang; }; return IO; })(); Caman.prototype.save = function() { if (typeof exports !== "undefined" && exports !== null) { return this.nodeSave.apply(this, arguments); } else { return this.browserSave.apply(this, arguments); } }; Caman.prototype.browserSave = function(type) { var image; if (type == null) { type = "png"; } type = type.toLowerCase(); image = this.toBase64(type).replace("image/" + type, "image/octet-stream"); return document.location.href = image; }; Caman.prototype.nodeSave = function(file, overwrite, callback) { var e, stats; if (overwrite == null) { overwrite = true; } if (callback == null) { callback = null; } try { stats = fs.statSync(file); if (stats.isFile() && !overwrite) { return false; } } catch (error) { e = error; Log.debug("Creating output file " + file); } return fs.writeFile(file, this.canvas.toBuffer(), function(err) { Log.debug("Finished writing to " + file); if (callback) { return callback.call(this, err); } }); }; Caman.prototype.toImage = function(type) { var img; img = new Image(); img.src = this.toBase64(type); img.width = this.dimensions.width; img.height = this.dimensions.height; if (window.devicePixelRatio) { img.width /= window.devicePixelRatio; img.height /= window.devicePixelRatio; } return img; }; Caman.prototype.toBase64 = function(type) { if (type == null) { type = "png"; } type = type.toLowerCase(); return this.renderingCanvas.toDataURL("image/" + type); }; IO = Caman.IO; Caman.Layer = (function() { function Layer(c1) { this.c = c1; this.filter = this.c; this.options = { blendingMode: 'normal', opacity: 1.0 }; this.layerID = Util.uniqid.get(); this.canvas = typeof exports !== "undefined" && exports !== null ? new Canvas() : document.createElement('canvas'); this.canvas.width = this.c.dimensions.width; this.canvas.height = this.c.dimensions.height; this.context = this.canvas.getContext('2d'); this.context.createImageData(this.canvas.width, this.canvas.height); this.imageData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); this.pixelData = this.imageData.data; } Layer.prototype.newLayer = function(cb) { return this.c.newLayer.call(this.c, cb); }; Layer.prototype.setBlendingMode = function(mode) { this.options.blendingMode = mode; return this; }; Layer.prototype.opacity = function(opacity) { this.options.opacity = opacity / 100; return this; }; Layer.prototype.copyParent = function() { var i, o, parentData, ref; parentData = this.c.pixelData; for (i = o = 0, ref = this.c.pixelData.length; o < ref; i = o += 4) { this.pixelData[i] = parentData[i]; this.pixelData[i + 1] = parentData[i + 1]; this.pixelData[i + 2] = parentData[i + 2]; this.pixelData[i + 3] = parentData[i + 3]; } return this; }; Layer.prototype.fillColor = function() { return this.c.fillColor.apply(this.c, arguments); }; Layer.prototype.overlayImage = function(image) { if (typeof image === "object") { image = image.src; } else if (typeof image === "string" && image[0] === "#") { image = $(image).src; } if (!image) { return this; } this.c.renderer.renderQueue.push({ type: Filter.Type.LoadOverlay, src: image, layer: this }); return this; }; Layer.prototype.applyToParent = function() { var i, layerData, o, parentData, ref, result, results, rgbaLayer, rgbaParent; parentData = this.c.pixelStack[this.c.pixelStack.length - 1]; layerData = this.c.pixelData; results = []; for (i = o = 0, ref = layerData.length; o < ref; i = o += 4) { rgbaParent = { r: parentData[i], g: parentData[i + 1], b: parentData[i + 2], a: parentData[i + 3] }; rgbaLayer = { r: layerData[i], g: layerData[i + 1], b: layerData[i + 2], a: layerData[i + 3] }; result = Blender.execute(this.options.blendingMode, rgbaLayer, rgbaParent); result.r = Util.clampRGB(result.r); result.g = Util.clampRGB(result.g); result.b = Util.clampRGB(result.b); if (result.a == null) { result.a = rgbaLayer.a; } parentData[i] = rgbaParent.r - ((rgbaParent.r - result.r) * (this.options.opacity * (result.a / 255))); parentData[i + 1] = rgbaParent.g - ((rgbaParent.g - result.g) * (this.options.opacity * (result.a / 255))); results.push(parentData[i + 2] = rgbaParent.b - ((rgbaParent.b - result.b) * (this.options.opacity * (result.a / 255)))); } return results; }; return Layer; })(); Layer = Caman.Layer; Caman.Logger = (function() { function Logger() { var len, name, o, ref; ref = ['log', 'info', 'warn', 'error']; for (o = 0, len = ref.length; o < len; o++) { name = ref[o]; this[name] = (function(name) { return function() { var args, e; args = 1 <= arguments.length ? slice1.call(arguments, 0) : []; if (!Caman.DEBUG) { return; } try { return console[name].apply(console, args); } catch (error) { e = error; return console[name](args); } }; })(name); } this.debug = this.log; } return Logger; })(); Log = new Caman.Logger(); Caman.Pixel = (function() { Pixel.coordinatesToLocation = function(x, y, width) { return (y * width + x) * 4; }; Pixel.locationToCoordinates = function(loc, width) { var x, y; y = Math.floor(loc / (width * 4)); x = (loc % (width * 4)) / 4; return { x: x, y: y }; }; function Pixel(r1, g1, b1, a1, c1) { this.r = r1 != null ? r1 : 0; this.g = g1 != null ? g1 : 0; this.b = b1 != null ? b1 : 0; this.a = a1 != null ? a1 : 255; this.c = c1 != null ? c1 : null; this.loc = 0; } Pixel.prototype.setContext = function(c) { return this.c = c; }; Pixel.prototype.locationXY = function() { var x, y; if (this.c == null) { throw "Requires a CamanJS context"; } y = this.c.dimensions.height - Math.floor(this.loc / (this.c.dimensions.width * 4)); x = (this.loc % (this.c.dimensions.width * 4)) / 4; return { x: x, y: y }; }; Pixel.prototype.pixelAtLocation = function(loc) { if (this.c == null) { throw "Requires a CamanJS context"; } return new Pixel(this.c.pixelData[loc], this.c.pixelData[loc + 1], this.c.pixelData[loc + 2], this.c.pixelData[loc + 3], this.c); }; Pixel.prototype.getPixelRelative = function(horiz, vert) { var newLoc; if (this.c == null) { throw "Requires a CamanJS context"; } newLoc = this.loc + (this.c.dimensions.width * 4 * (vert * -1)) + (4 * horiz); if (newLoc > this.c.pixelData.length || newLoc < 0) { return new Pixel(0, 0, 0, 255, this.c); } return this.pixelAtLocation(newLoc); }; Pixel.prototype.putPixelRelative = function(horiz, vert, rgba) { var nowLoc; if (this.c == null) { throw "Requires a CamanJS context"; } nowLoc = this.loc + (this.c.dimensions.width * 4 * (vert * -1)) + (4 * horiz); if (newLoc > this.c.pixelData.length || newLoc < 0) { return; } this.c.pixelData[newLoc] = rgba.r; this.c.pixelData[newLoc + 1] = rgba.g; this.c.pixelData[newLoc + 2] = rgba.b; this.c.pixelData[newLoc + 3] = rgba.a; return true; }; Pixel.prototype.getPixel = function(x, y) { var loc; if (this.c == null) { throw "Requires a CamanJS context"; } loc = this.coordinatesToLocation(x, y, this.width); return this.pixelAtLocation(loc); }; Pixel.prototype.putPixel = function(x, y, rgba) { var loc; if (this.c == null) { throw "Requires a CamanJS context"; } loc = this.coordinatesToLocation(x, y, this.width); this.c.pixelData[loc] = rgba.r; this.c.pixelData[loc + 1] = rgba.g; this.c.pixelData[loc + 2] = rgba.b; return this.c.pixelData[loc + 3] = rgba.a; }; Pixel.prototype.toString = function() { return this.toKey(); }; Pixel.prototype.toHex = function(includeAlpha) { var hex; if (includeAlpha == null) { includeAlpha = false; } hex = '#' + this.r.toString(16) + this.g.toString(16) + this.b.toString(16); if (includeAlpha) { return hex + this.a.toString(16); } else { return hex; } }; return Pixel; })(); Pixel = Caman.Pixel; Caman.Plugin = (function() { function Plugin() {} Plugin.plugins = {}; Plugin.register = function(name, plugin) { return this.plugins[name] = plugin; }; Plugin.execute = function(context, name, args) { return this.plugins[name].apply(context, args); }; return Plugin; })(); Plugin = Caman.Plugin; Caman.Renderer = (function() { Renderer.Blocks = Caman.NodeJS ? require('os').cpus().length : 4; function Renderer(c1) { this.c = c1; this.processNext = bind(this.processNext, this); this.renderQueue = []; this.modPixelData = null; } Renderer.prototype.add = function(job) { if (job == null) { return; } return this.renderQueue.push(job); }; Renderer.prototype.processNext = function() { var layer; if (this.renderQueue.length === 0) { Event.trigger(this, "renderFinished"); if (this.finishedFn != null) { this.finishedFn.call(this.c); } return this; } this.currentJob = this.renderQueue.shift(); switch (this.currentJob.type) { case Filter.Type.LayerDequeue: layer = this.c.canvasQueue.shift(); this.c.executeLayer(layer); return this.processNext(); case Filter.Type.LayerFinished: this.c.applyCurrentLayer(); this.c.popContext(); return this.processNext(); case Filter.Type.LoadOverlay: return this.loadOverlay(this.currentJob.layer, this.currentJob.src); case Filter.Type.Plugin: return this.executePlugin(); default: return this.executeFilter(); } }; Renderer.prototype.execute = function(callback) { this.finishedFn = callback; this.modPixelData = Util.dataArray(this.c.pixelData.length); return this.processNext(); }; Renderer.prototype.eachBlock = function(fn) { var blockN, blockPixelLength, bnum, end, f, i, lastBlockN, n, o, ref, results, start; this.blocksDone = 0; n = this.c.pixelData.length; blockPixelLength = Math.floor((n / 4) / Renderer.Blocks); blockN = blockPixelLength * 4; lastBlockN = blockN + ((n / 4) % Renderer.Blocks) * 4; results = []; for (i = o = 0, ref = Renderer.Blocks; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { start = i * blockN; end = start + (i === Renderer.Blocks - 1 ? lastBlockN : blockN); if (Caman.NodeJS) { f = Fiber((function(_this) { return function() { return fn.call(_this, i, start, end); }; })(this)); bnum = f.run(); results.push(this.blockFinished(bnum)); } else { results.push(setTimeout((function(_this) { return function(i, start, end) { return function() { return fn.call(_this, i, start, end); }; }; })(this)(i, start, end), 0)); } } return results; }; Renderer.prototype.executeFilter = function() { Event.trigger(this.c, "processStart", this.currentJob); if (this.currentJob.type === Filter.Type.Single) { return this.eachBlock(this.renderBlock); } else { return this.eachBlock(this.renderKernel); } }; Renderer.prototype.executePlugin = function() { Log.debug("Executing plugin " + this.currentJob.plugin); Plugin.execute(this.c, this.currentJob.plugin, this.currentJob.args); Log.debug("Plugin " + this.currentJob.plugin + " finished!"); return this.processNext(); }; Renderer.prototype.renderBlock = function(bnum, start, end) { var i, o, pixel, ref, ref1; Log.debug("Block #" + bnum + " - Filter: " + this.currentJob.name + ", Start: " + start + ", End: " + end); Event.trigger(this.c, "blockStarted", { blockNum: bnum, totalBlocks: Renderer.Blocks, startPixel: start, endPixel: end }); pixel = new Pixel(); pixel.setContext(this.c); for (i = o = ref = start, ref1 = end; o < ref1; i = o += 4) { pixel.loc = i; pixel.r = this.c.pixelData[i]; pixel.g = this.c.pixelData[i + 1]; pixel.b = this.c.pixelData[i + 2]; pixel.a = this.c.pixelData[i + 3]; if (this.currentJob.processFn) { this.currentJob.processFn(pixel); } this.c.pixelData[i] = Util.clampRGB(pixel.r); this.c.pixelData[i + 1] = Util.clampRGB(pixel.g); this.c.pixelData[i + 2] = Util.clampRGB(pixel.b); this.c.pixelData[i + 3] = Util.clampRGB(pixel.a); } if (Caman.NodeJS) { return Fiber["yield"](bnum); } else { return this.blockFinished(bnum); } }; Renderer.prototype.renderKernel = function(bnum, start, end) { var adjust, adjustSize, bias, builder, builderIndex, divisor, i, j, k, kernel, n, name, o, p, pixel, ref, ref1, ref2, ref3, ref4, ref5, res, u, w; name = this.currentJob.name; bias = this.currentJob.bias; divisor = this.currentJob.divisor; n = this.c.pixelData.length; adjust = this.currentJob.adjust; if (!adjust) { this.blockFinished(bnum); return; } adjustSize = Math.sqrt(adjust.length); kernel = []; Log.debug("Rendering kernel - Filter: " + this.currentJob.name); start = Math.max(start, this.c.dimensions.width * 4 * ((adjustSize - 1) / 2)); end = Math.min(end, n - (this.c.dimensions.width * 4 * ((adjustSize - 1) / 2))); builder = (adjustSize - 1) / 2; pixel = new Pixel(); pixel.setContext(this.c); for (i = o = ref = start, ref1 = end; o < ref1; i = o += 4) { pixel.loc = i; builderIndex = 0; for (j = u = ref2 = -builder, ref3 = builder; ref2 <= ref3 ? u <= ref3 : u >= ref3; j = ref2 <= ref3 ? ++u : --u) { for (k = w = ref4 = builder, ref5 = -builder; ref4 <= ref5 ? w <= ref5 : w >= ref5; k = ref4 <= ref5 ? ++w : --w) { p = pixel.getPixelRelative(j, k); kernel[builderIndex * 3] = p.r; kernel[builderIndex * 3 + 1] = p.g; kernel[builderIndex * 3 + 2] = p.b; builderIndex++; } } res = this.processKernel(adjust, kernel, divisor, bias); this.modPixelData[i] = Util.clampRGB(res.r); this.modPixelData[i + 1] = Util.clampRGB(res.g); this.modPixelData[i + 2] = Util.clampRGB(res.b); this.modPixelData[i + 3] = this.c.pixelData[i + 3]; } if (Caman.NodeJS) { return Fiber["yield"](bnum); } else { return this.blockFinished(bnum); } }; Renderer.prototype.blockFinished = function(bnum) { var i, o, ref; if (bnum >= 0) { Log.debug("Block #" + bnum + " finished! Filter: " + this.currentJob.name); } this.blocksDone++; Event.trigger(this.c, "blockFinished", { blockNum: bnum, blocksFinished: this.blocksDone, totalBlocks: Renderer.Blocks }); if (this.blocksDone === Renderer.Blocks) { if (this.currentJob.type === Filter.Type.Kernel) { for (i = o = 0, ref = this.c.pixelData.length; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { this.c.pixelData[i] = this.modPixelData[i]; } } if (bnum >= 0) { Log.debug("Filter " + this.currentJob.name + " finished!"); } Event.trigger(this.c, "processComplete", this.currentJob); return this.processNext(); } }; Renderer.prototype.processKernel = function(adjust, kernel, divisor, bias) { var i, o, ref, val; val = { r: 0, g: 0, b: 0 }; for (i = o = 0, ref = adjust.length; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { val.r += adjust[i] * kernel[i * 3]; val.g += adjust[i] * kernel[i * 3 + 1]; val.b += adjust[i] * kernel[i * 3 + 2]; } val.r = (val.r / divisor) + bias; val.g = (val.g / divisor) + bias; val.b = (val.b / divisor) + bias; return val; }; Renderer.prototype.loadOverlay = function(layer, src) { var img, proxyUrl; img = new Image(); img.onload = (function(_this) { return function() { layer.context.drawImage(img, 0, 0, _this.c.dimensions.width, _this.c.dimensions.height); layer.imageData = layer.context.getImageData(0, 0, _this.c.dimensions.width, _this.c.dimensions.height); layer.pixelData = layer.imageData.data; _this.c.pixelData = layer.pixelData; return _this.processNext(); }; })(this); proxyUrl = IO.remoteCheck(src); return img.src = proxyUrl != null ? proxyUrl : src; }; return Renderer; })(); Renderer = Caman.Renderer; Caman.Store = (function() { function Store() {} Store.items = {}; Store.has = function(search) { return this.items[search] != null; }; Store.get = function(search) { return this.items[search]; }; Store.put = function(name, obj) { return this.items[name] = obj; }; Store.execute = function(search, callback) { setTimeout((function(_this) { return function() { return callback.call(_this.get(search), _this.get(search)); }; })(this), 0); return this.get(search); }; Store.flush = function(name) { if (name == null) { name = false; } if (name) { return delete this.items[name]; } else { return this.items = {}; } }; return Store; })(); Store = Caman.Store; Blender.register("normal", function(rgbaLayer, rgbaParent) { return { r: rgbaLayer.r, g: rgbaLayer.g, b: rgbaLayer.b }; }); Blender.register("multiply", function(rgbaLayer, rgbaParent) { return { r: (rgbaLayer.r * rgbaParent.r) / 255, g: (rgbaLayer.g * rgbaParent.g) / 255, b: (rgbaLayer.b * rgbaParent.b) / 255 }; }); Blender.register("screen", function(rgbaLayer, rgbaParent) { return { r: 255 - (((255 - rgbaLayer.r) * (255 - rgbaParent.r)) / 255), g: 255 - (((255 - rgbaLayer.g) * (255 - rgbaParent.g)) / 255), b: 255 - (((255 - rgbaLayer.b) * (255 - rgbaParent.b)) / 255) }; }); Blender.register("overlay", function(rgbaLayer, rgbaParent) { var result; result = {}; result.r = rgbaParent.r > 128 ? 255 - 2 * (255 - rgbaLayer.r) * (255 - rgbaParent.r) / 255 : (rgbaParent.r * rgbaLayer.r * 2) / 255; result.g = rgbaParent.g > 128 ? 255 - 2 * (255 - rgbaLayer.g) * (255 - rgbaParent.g) / 255 : (rgbaParent.g * rgbaLayer.g * 2) / 255; result.b = rgbaParent.b > 128 ? 255 - 2 * (255 - rgbaLayer.b) * (255 - rgbaParent.b) / 255 : (rgbaParent.b * rgbaLayer.b * 2) / 255; return result; }); Blender.register("difference", function(rgbaLayer, rgbaParent) { return { r: rgbaLayer.r - rgbaParent.r, g: rgbaLayer.g - rgbaParent.g, b: rgbaLayer.b - rgbaParent.b }; }); Blender.register("addition", function(rgbaLayer, rgbaParent) { return { r: rgbaParent.r + rgbaLayer.r, g: rgbaParent.g + rgbaLayer.g, b: rgbaParent.b + rgbaLayer.b }; }); Blender.register("exclusion", function(rgbaLayer, rgbaParent) { return { r: 128 - 2 * (rgbaParent.r - 128) * (rgbaLayer.r - 128) / 255, g: 128 - 2 * (rgbaParent.g - 128) * (rgbaLayer.g - 128) / 255, b: 128 - 2 * (rgbaParent.b - 128) * (rgbaLayer.b - 128) / 255 }; }); Blender.register("softLight", function(rgbaLayer, rgbaParent) { var result; result = {}; result.r = rgbaParent.r > 128 ? 255 - ((255 - rgbaParent.r) * (255 - (rgbaLayer.r - 128))) / 255 : (rgbaParent.r * (rgbaLayer.r + 128)) / 255; result.g = rgbaParent.g > 128 ? 255 - ((255 - rgbaParent.g) * (255 - (rgbaLayer.g - 128))) / 255 : (rgbaParent.g * (rgbaLayer.g + 128)) / 255; result.b = rgbaParent.b > 128 ? 255 - ((255 - rgbaParent.b) * (255 - (rgbaLayer.b - 128))) / 255 : (rgbaParent.b * (rgbaLayer.b + 128)) / 255; return result; }); Blender.register("lighten", function(rgbaLayer, rgbaParent) { return { r: rgbaParent.r > rgbaLayer.r ? rgbaParent.r : rgbaLayer.r, g: rgbaParent.g > rgbaLayer.g ? rgbaParent.g : rgbaLayer.g, b: rgbaParent.b > rgbaLayer.b ? rgbaParent.b : rgbaLayer.b }; }); Blender.register("darken", function(rgbaLayer, rgbaParent) { return { r: rgbaParent.r > rgbaLayer.r ? rgbaLayer.r : rgbaParent.r, g: rgbaParent.g > rgbaLayer.g ? rgbaLayer.g : rgbaParent.g, b: rgbaParent.b > rgbaLayer.b ? rgbaLayer.b : rgbaParent.b }; }); Filter.register("fillColor", function() { var color; if (arguments.length === 1) { color = Convert.hexToRGB(arguments[0]); } else { color = { r: arguments[0], g: arguments[1], b: arguments[2] }; } return this.process("fillColor", function(rgba) { rgba.r = color.r; rgba.g = color.g; rgba.b = color.b; rgba.a = 255; return rgba; }); }); Filter.register("brightness", function(adjust) { adjust = Math.floor(255 * (adjust / 100)); return this.process("brightness", function(rgba) { rgba.r += adjust; rgba.g += adjust; rgba.b += adjust; return rgba; }); }); Filter.register("saturation", function(adjust) { adjust *= -0.01; return this.process("saturation", function(rgba) { var max; max = Math.max(rgba.r, rgba.g, rgba.b); if (rgba.r !== max) { rgba.r += (max - rgba.r) * adjust; } if (rgba.g !== max) { rgba.g += (max - rgba.g) * adjust; } if (rgba.b !== max) { rgba.b += (max - rgba.b) * adjust; } return rgba; }); }); Filter.register("vibrance", function(adjust) { adjust *= -1; return this.process("vibrance", function(rgba) { var amt, avg, max; max = Math.max(rgba.r, rgba.g, rgba.b); avg = (rgba.r + rgba.g + rgba.b) / 3; amt = ((Math.abs(max - avg) * 2 / 255) * adjust) / 100; if (rgba.r !== max) { rgba.r += (max - rgba.r) * amt; } if (rgba.g !== max) { rgba.g += (max - rgba.g) * amt; } if (rgba.b !== max) { rgba.b += (max - rgba.b) * amt; } return rgba; }); }); Filter.register("greyscale", function(adjust) { return this.process("greyscale", function(rgba) { var avg; avg = Calculate.luminance(rgba); rgba.r = avg; rgba.g = avg; rgba.b = avg; return rgba; }); }); Filter.register("contrast", function(adjust) { adjust = Math.pow((adjust + 100) / 100, 2); return this.process("contrast", function(rgba) { rgba.r /= 255; rgba.r -= 0.5; rgba.r *= adjust; rgba.r += 0.5; rgba.r *= 255; rgba.g /= 255; rgba.g -= 0.5; rgba.g *= adjust; rgba.g += 0.5; rgba.g *= 255; rgba.b /= 255; rgba.b -= 0.5; rgba.b *= adjust; rgba.b += 0.5; rgba.b *= 255; return rgba; }); }); Filter.register("hue", function(adjust) { return this.process("hue", function(rgba) { var b, g, h, hsv, r, ref; hsv = Convert.rgbToHSV(rgba.r, rgba.g, rgba.b); h = hsv.h * 100; h += Math.abs(adjust); h = h % 100; h /= 100; hsv.h = h; ref = Convert.hsvToRGB(hsv.h, hsv.s, hsv.v), r = ref.r, g = ref.g, b = ref.b; rgba.r = r; rgba.g = g; rgba.b = b; return rgba; }); }); Filter.register("colorize", function() { var level, rgb; if (arguments.length === 2) { rgb = Convert.hexToRGB(arguments[0]); level = arguments[1]; } else if (arguments.length === 4) { rgb = { r: arguments[0], g: arguments[1], b: arguments[2] }; level = arguments[3]; } return this.process("colorize", function(rgba) { rgba.r -= (rgba.r - rgb.r) * (level / 100); rgba.g -= (rgba.g - rgb.g) * (level / 100); rgba.b -= (rgba.b - rgb.b) * (level / 100); return rgba; }); }); Filter.register("invert", function() { return this.process("invert", function(rgba) { rgba.r = 255 - rgba.r; rgba.g = 255 - rgba.g; rgba.b = 255 - rgba.b; return rgba; }); }); Filter.register("sepia", function(adjust) { if (adjust == null) { adjust = 100; } adjust /= 100; return this.process("sepia", function(rgba) { rgba.r = Math.min(255, (rgba.r * (1 - (0.607 * adjust))) + (rgba.g * (0.769 * adjust)) + (rgba.b * (0.189 * adjust))); rgba.g = Math.min(255, (rgba.r * (0.349 * adjust)) + (rgba.g * (1 - (0.314 * adjust))) + (rgba.b * (0.168 * adjust))); rgba.b = Math.min(255, (rgba.r * (0.272 * adjust)) + (rgba.g * (0.534 * adjust)) + (rgba.b * (1 - (0.869 * adjust)))); return rgba; }); }); Filter.register("gamma", function(adjust) { return this.process("gamma", function(rgba) { rgba.r = Math.pow(rgba.r / 255, adjust) * 255; rgba.g = Math.pow(rgba.g / 255, adjust) * 255; rgba.b = Math.pow(rgba.b / 255, adjust) * 255; return rgba; }); }); Filter.register("noise", function(adjust) { adjust = Math.abs(adjust) * 2.55; return this.process("noise", function(rgba) { var rand; rand = Calculate.randomRange(adjust * -1, adjust); rgba.r += rand; rgba.g += rand; rgba.b += rand; return rgba; }); }); Filter.register("clip", function(adjust) { adjust = Math.abs(adjust) * 2.55; return this.process("clip", function(rgba) { if (rgba.r > 255 - adjust) { rgba.r = 255; } else if (rgba.r < adjust) { rgba.r = 0; } if (rgba.g > 255 - adjust) { rgba.g = 255; } else if (rgba.g < adjust) { rgba.g = 0; } if (rgba.b > 255 - adjust) { rgba.b = 255; } else if (rgba.b < adjust) { rgba.b = 0; } return rgba; }); }); Filter.register("channels", function(options) { var chan, value; if (typeof options !== "object") { return this; } for (chan in options) { if (!hasProp.call(options, chan)) continue; value = options[chan]; if (value === 0) { delete options[chan]; continue; } options[chan] /= 100; } if (options.length === 0) { return this; } return this.process("channels", function(rgba) { if (options.red != null) { if (options.red > 0) { rgba.r += (255 - rgba.r) * options.red; } else { rgba.r -= rgba.r * Math.abs(options.red); } } if (options.green != null) { if (options.green > 0) { rgba.g += (255 - rgba.g) * options.green; } else { rgba.g -= rgba.g * Math.abs(options.green); } } if (options.blue != null) { if (options.blue > 0) { rgba.b += (255 - rgba.b) * options.blue; } else { rgba.b -= rgba.b * Math.abs(options.blue); } } return rgba; }); }); Filter.register("curves", function() { var algo, bezier, chans, cps, end, i, last, o, ref, ref1, start, u; chans = arguments[0], cps = 2 <= arguments.length ? slice1.call(arguments, 1) : []; last = cps[cps.length - 1]; if (typeof last === "function") { algo = last; cps.pop(); } else if (typeof last === "string") { algo = Calculate[last]; cps.pop(); } else { algo = Calculate.bezier; } if (typeof chans === "string") { chans = chans.split(""); } if (chans[0] === "v") { chans = ['r', 'g', 'b']; } if (cps.length < 2) { throw "Invalid number of arguments to curves filter"; } bezier = algo(cps, 0, 255); start = cps[0]; if (start[0] > 0) { for (i = o = 0, ref = start[0]; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { bezier[i] = start[1]; } } end = cps[cps.length - 1]; if (end[0] < 255) { for (i = u = ref1 = end[0]; ref1 <= 255 ? u <= 255 : u >= 255; i = ref1 <= 255 ? ++u : --u) { bezier[i] = end[1]; } } return this.process("curves", function(rgba) { var ref2, w; for (i = w = 0, ref2 = chans.length; 0 <= ref2 ? w < ref2 : w > ref2; i = 0 <= ref2 ? ++w : --w) { rgba[chans[i]] = bezier[rgba[chans[i]]]; } return rgba; }); }); Filter.register("exposure", function(adjust) { var ctrl1, ctrl2, p; p = Math.abs(adjust) / 100; ctrl1 = [0, 255 * p]; ctrl2 = [255 - (255 * p), 255]; if (adjust < 0) { ctrl1 = ctrl1.reverse(); ctrl2 = ctrl2.reverse(); } return this.curves('rgb', [0, 0], ctrl1, ctrl2, [255, 255]); }); Caman.Plugin.register("crop", function(width, height, x, y) { var canvas, ctx; if (x == null) { x = 0; } if (y == null) { y = 0; } if (typeof exports !== "undefined" && exports !== null) { canvas = new Canvas(width, height); } else { canvas = document.createElement('canvas'); Util.copyAttributes(this.canvas, canvas); canvas.width = width; canvas.height = height; } ctx = canvas.getContext('2d'); ctx.drawImage(this.canvas, x, y, width, height, 0, 0, width, height); this.cropCoordinates = { x: x, y: y }; this.cropped = true; return this.replaceCanvas(canvas); }); Caman.Plugin.register("resize", function(newDims) { var canvas, ctx; if (newDims == null) { newDims = null; } if (newDims === null || ((newDims.width == null) && (newDims.height == null))) { Log.error("Invalid or missing dimensions given for resize"); return; } if (newDims.width == null) { newDims.width = this.canvas.width * newDims.height / this.canvas.height; } else if (newDims.height == null) { newDims.height = this.canvas.height * newDims.width / this.canvas.width; } if (typeof exports !== "undefined" && exports !== null) { canvas = new Canvas(newDims.width, newDims.height); } else { canvas = document.createElement('canvas'); Util.copyAttributes(this.canvas, canvas); canvas.width = newDims.width; canvas.height = newDims.height; } ctx = canvas.getContext('2d'); ctx.drawImage(this.canvas, 0, 0, this.canvas.width, this.canvas.height, 0, 0, newDims.width, newDims.height); this.resized = true; return this.replaceCanvas(canvas); }); Caman.Filter.register("crop", function() { return this.processPlugin("crop", Array.prototype.slice.call(arguments, 0)); }); Caman.Filter.register("resize", function() { return this.processPlugin("resize", Array.prototype.slice.call(arguments, 0)); }); }).call(this);