/** * Part of Picozu Image Editing application. * Visit https://www.picozu.com for more info. * The code is copyrighted by Picozu . * * @version 1.1.121413 * @package Workers * @application Picozu * @license www.picozu.com/license */ self.addEventListener('message', function (e) { function process(data) { data.type = (typeof data.type != 'undefined') ? data.type : 'rgb'; return { histogram: calculate(data.type, data.imageData.data), type: data.type } } self.postMessage(process(e.data)); }, false); function calculate(type, imgData) { var chans = [[]]; var maxCount = 0; var val; var subtypes = [type]; if (type === 'rgb') { chans = [ [], [], [] ]; subtypes = [ 'red', 'green', 'blue' ]; } else if (type === 'cmyk') { chans = [ [], [], [], [] ]; subtypes = [ 'cyan', 'magenta', 'yellow', 'kelvin' ]; } var step = 4; for (var i = 0, n = imgData.length; i < n; i += step) { if (type === 'rgb' || type === 'red' || type === 'green' || type === 'blue') { val = [imgData[i], imgData[i + 1], imgData[i + 2]]; } else if (type === 'cmyk' || type === 'cyan' || type === 'magenta' || type === 'yellow' || type === 'kelvin') { val = rgb2cmyk(imgData[i], imgData[i + 1], imgData[i + 2]); } else if (type === 'hue' || type === 'sat' || type === 'val') { val = rgb2hsv(imgData[i], imgData[i + 1], imgData[i + 2]); } if (type === 'red' || type === 'hue' || type === 'cyan') { val = [val[0]]; } else if (type === 'green' || type === 'sat' || type === 'magenta') { val = [val[1]]; } else if (type === 'blue' || type === 'val' || type === 'yellow') { val = [val[2]]; } else if (type === 'kelvin') { val = [val[3]]; } for (var y = 0, m = val.length; y < m; y++) { if (val[y] in chans[y]) { chans[y][val[y]]++; } else { chans[y][val[y]] = 1; } if (chans[y][val[y]] > maxCount) { maxCount = chans[y][val[y]]; } } } if (maxCount === 0) { return null; } else { return { subtypes: subtypes, chans: chans, maxCount: maxCount } } } function rgb2hsv(red, green, blue) { red /= 255; green /= 255; blue /= 255; var hue, sat, val, min = Math.min(red, green, blue), max = Math.max(red, green, blue), delta = max - min, val = max; if (delta === 0) { hue = sat = 0; } else { sat = delta / max; if (max === red) { hue = (green - blue) / delta; } else if (max === green) { hue = (blue - red) / delta + 2; } else if (max === blue) { hue = (red - green) / delta + 4; } hue /= 6; if (hue < 0) { hue += 1; } } return [ Math.round(hue * 255), Math.round(sat * 255), Math.round(val * 255) ]; } function rgb2cmyk(red, green, blue) { var cyan = 1 - red / 255; var magenta = 1 - green / 255; var yellow = 1 - blue / 255; var black = Math.min(cyan, magenta, yellow, 1); if (black === 1) { cyan = magenta = yellow = 0; } else { var w = 1 - black; cyan = (cyan - black) / w; magenta = (magenta - black) / w; yellow = (yellow - black) / w; } return [ Math.round(cyan * 255), Math.round(magenta * 255), Math.round(yellow * 255), Math.round(black * 255) ]; }