UNPKG

webdriverio-automation

Version:

WebdriverIO-Automation android ios project

1,403 lines (1,325 loc) 141 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("iq", [], factory); else if(typeof exports === 'object') exports["iq"] = factory(); else root["iq"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * iq.ts - Image Quantization Library */ var constants = __webpack_require__(1); exports.constants = constants; var conversion = __webpack_require__(3); exports.conversion = conversion; var distance = __webpack_require__(12); exports.distance = distance; var palette = __webpack_require__(20); exports.palette = palette; var image = __webpack_require__(30); exports.image = image; var quality = __webpack_require__(35); exports.quality = quality; var utils = __webpack_require__(37); exports.utils = utils; /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * constants.ts - part of Image Quantization Library */ var bt709 = __webpack_require__(2); exports.bt709 = bt709; /***/ }, /* 2 */ /***/ function(module, exports) { /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * constants.ts - part of Image Quantization Library */ "use strict"; /** * sRGB (based on ITU-R Recommendation BT.709) * http://en.wikipedia.org/wiki/SRGB */ var Y; (function (Y) { Y[Y["RED"] = 0.2126] = "RED"; Y[Y["GREEN"] = 0.7152] = "GREEN"; Y[Y["BLUE"] = 0.0722] = "BLUE"; Y[Y["WHITE"] = 1] = "WHITE"; })(Y || (Y = {})); exports.Y = Y; var x; (function (x) { x[x["RED"] = 0.64] = "RED"; x[x["GREEN"] = 0.3] = "GREEN"; x[x["BLUE"] = 0.15] = "BLUE"; x[x["WHITE"] = 0.3127] = "WHITE"; })(x || (x = {})); exports.x = x; var y; (function (y) { y[y["RED"] = 0.33] = "RED"; y[y["GREEN"] = 0.6] = "GREEN"; y[y["BLUE"] = 0.06] = "BLUE"; y[y["WHITE"] = 0.329] = "WHITE"; })(y || (y = {})); exports.y = y; /***/ }, /* 3 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * iq.ts - Image Quantization Library */ var rgb2xyz_1 = __webpack_require__(4); exports.rgb2xyz = rgb2xyz_1.rgb2xyz; var rgb2hsl_1 = __webpack_require__(5); exports.rgb2hsl = rgb2hsl_1.rgb2hsl; var rgb2lab_1 = __webpack_require__(7); exports.rgb2lab = rgb2lab_1.rgb2lab; var lab2xyz_1 = __webpack_require__(9); exports.lab2xyz = lab2xyz_1.lab2xyz; var lab2rgb_1 = __webpack_require__(10); exports.lab2rgb = lab2rgb_1.lab2rgb; var xyz2lab_1 = __webpack_require__(8); exports.xyz2lab = xyz2lab_1.xyz2lab; var xyz2rgb_1 = __webpack_require__(11); exports.xyz2rgb = xyz2rgb_1.xyz2rgb; /***/ }, /* 4 */ /***/ function(module, exports) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * rgb2xyz.ts - part of Image Quantization Library */ function correctGamma(n) { return n > 0.04045 ? Math.pow((n + 0.055) / 1.055, 2.4) : n / 12.92; } function rgb2xyz(r, g, b) { // gamma correction, see https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation r = correctGamma(r / 255); g = correctGamma(g / 255); b = correctGamma(b / 255); // Observer. = 2°, Illuminant = D65 return { 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 }; } exports.rgb2xyz = rgb2xyz; /***/ }, /* 5 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * rgb2hsl.ts - part of Image Quantization Library */ var arithmetic_1 = __webpack_require__(6); /** * Calculate HSL from RGB * Hue is in degrees [0..360] * Lightness: [0..1] * Saturation: [0..1] * http://web.archive.org/web/20060914040436/http://local.wasp.uwa.edu.au/~pbourke/colour/hsl/ */ function rgb2hsl(r, g, b) { var min = arithmetic_1.min3(r, g, b), max = arithmetic_1.max3(r, g, b), delta = max - min, l = (min + max) / 510; var s = 0; if (l > 0 && l < 1) s = delta / (l < 0.5 ? (max + min) : (510 - max - min)); var h = 0; if (delta > 0) { if (max === r) { h = (g - b) / delta; } else if (max === g) { h = (2 + (b - r) / delta); } else { h = (4 + (r - g) / delta); } h *= 60; if (h < 0) h += 360; } return { h: h, s: s, l: l }; } exports.rgb2hsl = rgb2hsl; /***/ }, /* 6 */ /***/ function(module, exports) { "use strict"; function degrees2radians(n) { return n * (Math.PI / 180); } exports.degrees2radians = degrees2radians; function max3(a, b, c) { var m = a; (m < b) && (m = b); (m < c) && (m = c); return m; } exports.max3 = max3; function min3(a, b, c) { var m = a; (m > b) && (m = b); (m > c) && (m = c); return m; } exports.min3 = min3; function intInRange(value, low, high) { if (value > high) value = high; if (value < low) value = low; return value | 0; } exports.intInRange = intInRange; function inRange0to255Rounded(n) { n = Math.round(n); if (n > 255) n = 255; else if (n < 0) n = 0; return n; } exports.inRange0to255Rounded = inRange0to255Rounded; function inRange0to255(n) { if (n > 255) n = 255; else if (n < 0) n = 0; return n; } exports.inRange0to255 = inRange0to255; function stableSort(arrayToSort, callback) { var type = typeof arrayToSort[0]; var sorted; if (type === "number" || type === "string") { var ord_1 = Object.create(null); for (var i = 0, l = arrayToSort.length; i < l; i++) { var val = arrayToSort[i]; if (ord_1[val] || ord_1[val] === 0) continue; ord_1[val] = i; } sorted = arrayToSort.sort(function (a, b) { return callback(a, b) || ord_1[a] - ord_1[b]; }); } else { var ord2_1 = arrayToSort.slice(0); sorted = arrayToSort.sort(function (a, b) { return callback(a, b) || ord2_1.indexOf(a) - ord2_1.indexOf(b); }); } return sorted; } exports.stableSort = stableSort; /***/ }, /* 7 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * rgb2lab.ts - part of Image Quantization Library */ var rgb2xyz_1 = __webpack_require__(4); var xyz2lab_1 = __webpack_require__(8); function rgb2lab(r, g, b) { var xyz = rgb2xyz_1.rgb2xyz(r, g, b); return xyz2lab_1.xyz2lab(xyz.x, xyz.y, xyz.z); } exports.rgb2lab = rgb2lab; /***/ }, /* 8 */ /***/ function(module, exports) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * xyz2lab.ts - part of Image Quantization Library */ var refX = 0.95047, //ref_X = 95.047 Observer= 2°, Illuminant= D65 refY = 1.00000, //ref_Y = 100.000 refZ = 1.08883; //ref_Z = 108.883 function pivot(n) { return n > 0.008856 ? Math.pow(n, 1 / 3) : (7.787 * n + 16 / 116); } function xyz2lab(x, y, z) { x = pivot(x / refX); y = pivot(y / refY); z = pivot(z / refZ); if ((116 * y) - 16 < 0) throw new Error("xxx"); return { L: Math.max(0, (116 * y) - 16), a: 500 * (x - y), b: 200 * (y - z) }; } exports.xyz2lab = xyz2lab; /***/ }, /* 9 */ /***/ function(module, exports) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * lab2xyz.ts - part of Image Quantization Library */ var refX = 0.95047, //ref_X = 95.047 Observer= 2°, Illuminant = D65 refY = 1.00000, //ref_Y = 100.000 refZ = 1.08883; //ref_Z = 108.883 function pivot(n) { return n > 0.206893034 ? Math.pow(n, 3) : (n - 16 / 116) / 7.787; } function lab2xyz(L, a, b) { var y = (L + 16) / 116, x = a / 500 + y, z = y - b / 200; return { x: refX * pivot(x), y: refY * pivot(y), z: refZ * pivot(z) }; } exports.lab2xyz = lab2xyz; /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * lab2rgb.ts - part of Image Quantization Library */ var lab2xyz_1 = __webpack_require__(9); var xyz2rgb_1 = __webpack_require__(11); function lab2rgb(L, a, b) { var xyz = lab2xyz_1.lab2xyz(L, a, b); return xyz2rgb_1.xyz2rgb(xyz.x, xyz.y, xyz.z); } exports.lab2rgb = lab2rgb; /***/ }, /* 11 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * xyz2rgb.ts - part of Image Quantization Library */ var arithmetic_1 = __webpack_require__(6); // gamma correction, see https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation function correctGamma(n) { return n > 0.0031308 ? 1.055 * Math.pow(n, 1 / 2.4) - 0.055 : 12.92 * n; } function xyz2rgb(x, y, z) { // Observer. = 2°, Illuminant = D65 var r = correctGamma(x * 3.2406 + y * -1.5372 + z * -0.4986), g = correctGamma(x * -0.9689 + y * 1.8758 + z * 0.0415), b = correctGamma(x * 0.0557 + y * -0.2040 + z * 1.0570); return { r: arithmetic_1.inRange0to255Rounded(r * 255), g: arithmetic_1.inRange0to255Rounded(g * 255), b: arithmetic_1.inRange0to255Rounded(b * 255) }; } exports.xyz2rgb = xyz2rgb; /***/ }, /* 12 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * iq.ts - Image Quantization Library */ var abstractDistanceCalculator_1 = __webpack_require__(13); exports.AbstractDistanceCalculator = abstractDistanceCalculator_1.AbstractDistanceCalculator; var cie94_1 = __webpack_require__(14); exports.CIE94Textiles = cie94_1.CIE94Textiles; exports.CIE94GraphicArts = cie94_1.CIE94GraphicArts; var ciede2000_1 = __webpack_require__(15); exports.CIEDE2000 = ciede2000_1.CIEDE2000; var cmetric_1 = __webpack_require__(16); exports.CMETRIC = cmetric_1.CMETRIC; var euclidean_1 = __webpack_require__(17); exports.AbstractEuclidean = euclidean_1.AbstractEuclidean; exports.Euclidean = euclidean_1.Euclidean; exports.EuclideanRgbQuantWOAlpha = euclidean_1.EuclideanRgbQuantWOAlpha; exports.EuclideanRgbQuantWithAlpha = euclidean_1.EuclideanRgbQuantWithAlpha; var manhattan_1 = __webpack_require__(18); exports.AbstractManhattan = manhattan_1.AbstractManhattan; exports.Manhattan = manhattan_1.Manhattan; exports.ManhattanSRGB = manhattan_1.ManhattanSRGB; exports.ManhattanNommyde = manhattan_1.ManhattanNommyde; var pngQuant_1 = __webpack_require__(19); exports.PNGQUANT = pngQuant_1.PNGQUANT; /***/ }, /* 13 */ /***/ function(module, exports) { "use strict"; var AbstractDistanceCalculator = (function () { function AbstractDistanceCalculator() { this._setDefaults(); // set default maximal color component deltas (255 - 0 = 255) this.setWhitePoint(255, 255, 255, 255); } AbstractDistanceCalculator.prototype.setWhitePoint = function (r, g, b, a) { this._whitePoint = { r: (r > 0) ? 255 / r : 0, g: (g > 0) ? 255 / g : 0, b: (b > 0) ? 255 / b : 0, a: (a > 0) ? 255 / a : 0 }; this._maxDistance = this.calculateRaw(r, g, b, a, 0, 0, 0, 0); }; AbstractDistanceCalculator.prototype.calculateNormalized = function (colorA, colorB) { return this.calculateRaw(colorA.r, colorA.g, colorA.b, colorA.a, colorB.r, colorB.g, colorB.b, colorB.a) / this._maxDistance; }; AbstractDistanceCalculator.prototype._setDefaults = function () { }; return AbstractDistanceCalculator; }()); exports.AbstractDistanceCalculator = AbstractDistanceCalculator; /***/ }, /* 14 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * cie94.ts - part of Image Quantization Library */ var abstractDistanceCalculator_1 = __webpack_require__(13); var rgb2lab_1 = __webpack_require__(7); var arithmetic_1 = __webpack_require__(6); /** * CIE94 method of delta-e * http://en.wikipedia.org/wiki/Color_difference#CIE94 */ var AbstractCIE94 = (function (_super) { __extends(AbstractCIE94, _super); function AbstractCIE94() { _super.apply(this, arguments); } AbstractCIE94.prototype.calculateRaw = function (r1, g1, b1, a1, r2, g2, b2, a2) { var lab1 = rgb2lab_1.rgb2lab(arithmetic_1.inRange0to255(r1 * this._whitePoint.r), arithmetic_1.inRange0to255(g1 * this._whitePoint.g), arithmetic_1.inRange0to255(b1 * this._whitePoint.b)), lab2 = rgb2lab_1.rgb2lab(arithmetic_1.inRange0to255(r2 * this._whitePoint.r), arithmetic_1.inRange0to255(g2 * this._whitePoint.g), arithmetic_1.inRange0to255(b2 * this._whitePoint.b)); var dL = lab1.L - lab2.L, dA = lab1.a - lab2.a, dB = lab1.b - lab2.b, c1 = Math.sqrt(lab1.a * lab1.a + lab1.b * lab1.b), c2 = Math.sqrt(lab2.a * lab2.a + lab2.b * lab2.b), dC = c1 - c2; var deltaH = dA * dA + dB * dB - dC * dC; deltaH = deltaH < 0 ? 0 : Math.sqrt(deltaH); var dAlpha = (a2 - a1) * this._whitePoint.a * this._kA; // TODO: add alpha channel support return Math.sqrt(Math.pow(dL / this._Kl, 2) + Math.pow(dC / (1.0 + this._K1 * c1), 2) + Math.pow(deltaH / (1.0 + this._K2 * c1), 2) + Math.pow(dAlpha, 2)); }; return AbstractCIE94; }(abstractDistanceCalculator_1.AbstractDistanceCalculator)); exports.AbstractCIE94 = AbstractCIE94; var CIE94Textiles = (function (_super) { __extends(CIE94Textiles, _super); function CIE94Textiles() { _super.apply(this, arguments); } CIE94Textiles.prototype._setDefaults = function () { this._Kl = 2.0; this._K1 = 0.048; this._K2 = 0.014; this._kA = 0.25 * 50 / 255; }; return CIE94Textiles; }(AbstractCIE94)); exports.CIE94Textiles = CIE94Textiles; var CIE94GraphicArts = (function (_super) { __extends(CIE94GraphicArts, _super); function CIE94GraphicArts() { _super.apply(this, arguments); } CIE94GraphicArts.prototype._setDefaults = function () { this._Kl = 1.0; this._K1 = 0.045; this._K2 = 0.015; this._kA = 0.25 * 100 / 255; }; return CIE94GraphicArts; }(AbstractCIE94)); exports.CIE94GraphicArts = CIE94GraphicArts; /***/ }, /* 15 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * ciede2000.ts - part of Image Quantization Library */ var abstractDistanceCalculator_1 = __webpack_require__(13); var rgb2lab_1 = __webpack_require__(7); var arithmetic_1 = __webpack_require__(6); /** * CIEDE2000 algorithm - Adapted from Sharma et al's MATLAB implementation at * http://www.ece.rochester.edu/~gsharma/ciede2000/ */ var CIEDE2000 = (function (_super) { __extends(CIEDE2000, _super); function CIEDE2000() { _super.apply(this, arguments); } CIEDE2000.prototype.calculateRaw = function (r1, g1, b1, a1, r2, g2, b2, a2) { var lab1 = rgb2lab_1.rgb2lab(arithmetic_1.inRange0to255(r1 * this._whitePoint.r), arithmetic_1.inRange0to255(g1 * this._whitePoint.g), arithmetic_1.inRange0to255(b1 * this._whitePoint.b)), lab2 = rgb2lab_1.rgb2lab(arithmetic_1.inRange0to255(r2 * this._whitePoint.r), arithmetic_1.inRange0to255(g2 * this._whitePoint.g), arithmetic_1.inRange0to255(b2 * this._whitePoint.b)), dA = (a2 - a1) * this._whitePoint.a * CIEDE2000._kA, dE2 = this.calculateRawInLab(lab1, lab2); return Math.sqrt(dE2 + dA * dA); }; CIEDE2000.prototype.calculateRawInLab = function (Lab1, Lab2) { // Get L,a,b values for color 1 var L1 = Lab1.L, a1 = Lab1.a, b1 = Lab1.b; // Get L,a,b values for color 2 var L2 = Lab2.L, a2 = Lab2.a, b2 = Lab2.b; // Calculate Cprime1, Cprime2, Cabbar var C1 = Math.sqrt(a1 * a1 + b1 * b1), C2 = Math.sqrt(a2 * a2 + b2 * b2), pow_a_C1_C2_to_7 = Math.pow((C1 + C2) / 2.0, 7.0), G = 0.5 * (1.0 - Math.sqrt(pow_a_C1_C2_to_7 / (pow_a_C1_C2_to_7 + CIEDE2000._pow25to7))), //25^7 a1p = (1.0 + G) * a1, a2p = (1.0 + G) * a2, C1p = Math.sqrt(a1p * a1p + b1 * b1), C2p = Math.sqrt(a2p * a2p + b2 * b2), C1pC2p = C1p * C2p, // Angles in Degree. h1p = CIEDE2000._calculatehp(b1, a1p), h2p = CIEDE2000._calculatehp(b2, a2p), h_bar = Math.abs(h1p - h2p), dLp = L2 - L1, dCp = C2p - C1p, dHp = CIEDE2000._calculate_dHp(C1pC2p, h_bar, h2p, h1p), ahp = CIEDE2000._calculate_ahp(C1pC2p, h_bar, h1p, h2p), T = CIEDE2000._calculateT(ahp), aCp = (C1p + C2p) / 2.0, aLp_minus_50_square = Math.pow((L1 + L2) / 2.0 - 50.0, 2.0), S_L = 1.0 + (.015 * aLp_minus_50_square) / Math.sqrt(20.0 + aLp_minus_50_square), S_C = 1.0 + .045 * aCp, S_H = 1.0 + .015 * T * aCp, R_T = CIEDE2000._calculateRT(ahp, aCp), dLpSL = dLp / S_L, // S_L * kL, where kL is 1.0 dCpSC = dCp / S_C, // S_C * kC, where kC is 1.0 dHpSH = dHp / S_H; // S_H * kH, where kH is 1.0 return Math.pow(dLpSL, 2) + Math.pow(dCpSC, 2) + Math.pow(dHpSH, 2) + R_T * dCpSC * dHpSH; }; CIEDE2000._calculatehp = function (b, ap) { var hp = Math.atan2(b, ap); if (hp >= 0) return hp; return hp + CIEDE2000._deg360InRad; }; CIEDE2000._calculateRT = function (ahp, aCp) { var aCp_to_7 = Math.pow(aCp, 7.0), R_C = 2.0 * Math.sqrt(aCp_to_7 / (aCp_to_7 + CIEDE2000._pow25to7)), // 25^7 delta_theta = CIEDE2000._deg30InRad * Math.exp(-Math.pow((ahp - CIEDE2000._deg275InRad) / CIEDE2000._deg25InRad, 2.0)); return -Math.sin(2.0 * delta_theta) * R_C; }; CIEDE2000._calculateT = function (ahp) { return 1.0 - .17 * Math.cos(ahp - CIEDE2000._deg30InRad) + .24 * Math.cos(ahp * 2.0) + .32 * Math.cos(ahp * 3.0 + CIEDE2000._deg6InRad) - .2 * Math.cos(ahp * 4.0 - CIEDE2000._deg63InRad); }; CIEDE2000._calculate_ahp = function (C1pC2p, h_bar, h1p, h2p) { var hpSum = h1p + h2p; if (C1pC2p == 0) return hpSum; if (h_bar <= CIEDE2000._deg180InRad) return hpSum / 2.0; if (hpSum < CIEDE2000._deg360InRad) return (hpSum + CIEDE2000._deg360InRad) / 2.0; return (hpSum - CIEDE2000._deg360InRad) / 2.0; }; CIEDE2000._calculate_dHp = function (C1pC2p, h_bar, h2p, h1p) { var dhp; if (C1pC2p == 0) { dhp = 0; } else if (h_bar <= CIEDE2000._deg180InRad) { dhp = h2p - h1p; } else if (h2p <= h1p) { dhp = h2p - h1p + CIEDE2000._deg360InRad; } else { dhp = h2p - h1p - CIEDE2000._deg360InRad; } return 2.0 * Math.sqrt(C1pC2p) * Math.sin(dhp / 2.0); }; /** * Weight in distance: 0.25 * Max DeltaE: 100 * Max DeltaA: 255 */ CIEDE2000._kA = 0.25 * 100 / 255; CIEDE2000._pow25to7 = Math.pow(25, 7); CIEDE2000._deg360InRad = arithmetic_1.degrees2radians(360); CIEDE2000._deg180InRad = arithmetic_1.degrees2radians(180); CIEDE2000._deg30InRad = arithmetic_1.degrees2radians(30); CIEDE2000._deg6InRad = arithmetic_1.degrees2radians(6); CIEDE2000._deg63InRad = arithmetic_1.degrees2radians(63); CIEDE2000._deg275InRad = arithmetic_1.degrees2radians(275); CIEDE2000._deg25InRad = arithmetic_1.degrees2radians(25); return CIEDE2000; }(abstractDistanceCalculator_1.AbstractDistanceCalculator)); exports.CIEDE2000 = CIEDE2000; /***/ }, /* 16 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * cmetric.ts - part of Image Quantization Library */ var abstractDistanceCalculator_1 = __webpack_require__(13); /** * TODO: Name it: http://www.compuphase.com/cmetric.htm */ var CMETRIC = (function (_super) { __extends(CMETRIC, _super); function CMETRIC() { _super.apply(this, arguments); } CMETRIC.prototype.calculateRaw = function (r1, g1, b1, a1, r2, g2, b2, a2) { var rmean = (r1 + r2) / 2 * this._whitePoint.r, r = (r1 - r2) * this._whitePoint.r, g = (g1 - g2) * this._whitePoint.g, b = (b1 - b2) * this._whitePoint.b, dE = ((((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8)), dA = (a2 - a1) * this._whitePoint.a; return Math.sqrt(dE + dA * dA); }; return CMETRIC; }(abstractDistanceCalculator_1.AbstractDistanceCalculator)); exports.CMETRIC = CMETRIC; /***/ }, /* 17 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * euclidean.ts - part of Image Quantization Library */ var abstractDistanceCalculator_1 = __webpack_require__(13); var bt709_1 = __webpack_require__(2); /** * Euclidean color distance */ var AbstractEuclidean = (function (_super) { __extends(AbstractEuclidean, _super); function AbstractEuclidean() { _super.apply(this, arguments); } AbstractEuclidean.prototype.calculateRaw = function (r1, g1, b1, a1, r2, g2, b2, a2) { var dR = r2 - r1, dG = g2 - g1, dB = b2 - b1, dA = a2 - a1; return Math.sqrt(this._kR * dR * dR + this._kG * dG * dG + this._kB * dB * dB + this._kA * dA * dA); }; return AbstractEuclidean; }(abstractDistanceCalculator_1.AbstractDistanceCalculator)); exports.AbstractEuclidean = AbstractEuclidean; var Euclidean = (function (_super) { __extends(Euclidean, _super); function Euclidean() { _super.apply(this, arguments); } Euclidean.prototype._setDefaults = function () { this._kR = 1; this._kG = 1; this._kB = 1; this._kA = 1; }; return Euclidean; }(AbstractEuclidean)); exports.Euclidean = Euclidean; /** * Euclidean color distance (RgbQuant modification w Alpha) */ var EuclideanRgbQuantWithAlpha = (function (_super) { __extends(EuclideanRgbQuantWithAlpha, _super); function EuclideanRgbQuantWithAlpha() { _super.apply(this, arguments); } EuclideanRgbQuantWithAlpha.prototype._setDefaults = function () { this._kR = bt709_1.Y.RED; this._kG = bt709_1.Y.GREEN; this._kB = bt709_1.Y.BLUE; // TODO: what is the best coefficient below? this._kA = 1; }; return EuclideanRgbQuantWithAlpha; }(AbstractEuclidean)); exports.EuclideanRgbQuantWithAlpha = EuclideanRgbQuantWithAlpha; /** * Euclidean color distance (RgbQuant modification w/o Alpha) */ var EuclideanRgbQuantWOAlpha = (function (_super) { __extends(EuclideanRgbQuantWOAlpha, _super); function EuclideanRgbQuantWOAlpha() { _super.apply(this, arguments); } EuclideanRgbQuantWOAlpha.prototype._setDefaults = function () { this._kR = bt709_1.Y.RED; this._kG = bt709_1.Y.GREEN; this._kB = bt709_1.Y.BLUE; this._kA = 0; }; return EuclideanRgbQuantWOAlpha; }(AbstractEuclidean)); exports.EuclideanRgbQuantWOAlpha = EuclideanRgbQuantWOAlpha; /***/ }, /* 18 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * manhattanNeuQuant.ts - part of Image Quantization Library */ var abstractDistanceCalculator_1 = __webpack_require__(13); var bt709_1 = __webpack_require__(2); /** * Manhattan distance (NeuQuant modification) - w/o sRGB coefficients */ var AbstractManhattan = (function (_super) { __extends(AbstractManhattan, _super); function AbstractManhattan() { _super.apply(this, arguments); } AbstractManhattan.prototype.calculateRaw = function (r1, g1, b1, a1, r2, g2, b2, a2) { var dR = r2 - r1, dG = g2 - g1, dB = b2 - b1, dA = a2 - a1; if (dR < 0) dR = 0 - dR; if (dG < 0) dG = 0 - dG; if (dB < 0) dB = 0 - dB; if (dA < 0) dA = 0 - dA; return this._kR * dR + this._kG * dG + this._kB * dB + this._kA * dA; }; return AbstractManhattan; }(abstractDistanceCalculator_1.AbstractDistanceCalculator)); exports.AbstractManhattan = AbstractManhattan; var Manhattan = (function (_super) { __extends(Manhattan, _super); function Manhattan() { _super.apply(this, arguments); } Manhattan.prototype._setDefaults = function () { this._kR = 1; this._kG = 1; this._kB = 1; this._kA = 1; }; return Manhattan; }(AbstractManhattan)); exports.Manhattan = Manhattan; /** * Manhattan distance (Nommyde modification) * https://github.com/igor-bezkrovny/image-quantization/issues/4#issuecomment-235155320 */ var ManhattanNommyde = (function (_super) { __extends(ManhattanNommyde, _super); function ManhattanNommyde() { _super.apply(this, arguments); } ManhattanNommyde.prototype._setDefaults = function () { this._kR = 0.4984; this._kG = 0.8625; this._kB = 0.2979; // TODO: what is the best coefficient below? this._kA = 1; }; return ManhattanNommyde; }(AbstractManhattan)); exports.ManhattanNommyde = ManhattanNommyde; /** * Manhattan distance (sRGB coefficients) */ var ManhattanSRGB = (function (_super) { __extends(ManhattanSRGB, _super); function ManhattanSRGB() { _super.apply(this, arguments); } ManhattanSRGB.prototype._setDefaults = function () { this._kR = bt709_1.Y.RED; this._kG = bt709_1.Y.GREEN; this._kB = bt709_1.Y.BLUE; // TODO: what is the best coefficient below? this._kA = 1; }; return ManhattanSRGB; }(AbstractManhattan)); exports.ManhattanSRGB = ManhattanSRGB; /***/ }, /* 19 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * pngQuant.ts - part of Image Quantization Library */ var abstractDistanceCalculator_1 = __webpack_require__(13); /** * TODO: check quality of this distance equation * TODO: ask author for usage rights * taken from: * {@link http://stackoverflow.com/questions/4754506/color-similarity-distance-in-rgba-color-space/8796867#8796867} * {@link https://github.com/pornel/pngquant/blob/cc39b47799a7ff2ef17b529f9415ff6e6b213b8f/lib/pam.h#L148} */ var PNGQUANT = (function (_super) { __extends(PNGQUANT, _super); function PNGQUANT() { _super.apply(this, arguments); } /** * Author's comments * px_b.rgb = px.rgb + 0*(1-px.a) // blend px on black * px_b.a = px.a + 1*(1-px.a) * px_w.rgb = px.rgb + 1*(1-px.a) // blend px on white * px_w.a = px.a + 1*(1-px.a) * px_b.rgb = px.rgb // difference same as in opaque RGB * px_b.a = 1 * px_w.rgb = px.rgb - px.a // difference simplifies to formula below * px_w.a = 1 * (px.rgb - px.a) - (py.rgb - py.a) * (px.rgb - py.rgb) + (py.a - px.a) * */ PNGQUANT.prototype.calculateRaw = function (r1, g1, b1, a1, r2, g2, b2, a2) { var alphas = (a2 - a1) * this._whitePoint.a; return this._colordifference_ch(r1 * this._whitePoint.r, r2 * this._whitePoint.r, alphas) + this._colordifference_ch(g1 * this._whitePoint.g, g2 * this._whitePoint.g, alphas) + this._colordifference_ch(b1 * this._whitePoint.b, b2 * this._whitePoint.b, alphas); }; PNGQUANT.prototype._colordifference_ch = function (x, y, alphas) { // maximum of channel blended on white, and blended on black // premultiplied alpha and backgrounds 0/1 shorten the formula var black = x - y, white = black + alphas; return black * black + white * white; }; return PNGQUANT; }(abstractDistanceCalculator_1.AbstractDistanceCalculator)); exports.PNGQUANT = PNGQUANT; /***/ }, /* 20 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var neuquant_1 = __webpack_require__(21); exports.NeuQuant = neuquant_1.NeuQuant; var neuquantFloat_1 = __webpack_require__(25); exports.NeuQuantFloat = neuquantFloat_1.NeuQuantFloat; var rgbquant_1 = __webpack_require__(26); exports.RGBQuant = rgbquant_1.RGBQuant; var colorHistogram_1 = __webpack_require__(27); exports.ColorHistogram = colorHistogram_1.ColorHistogram; var wuQuant_1 = __webpack_require__(29); exports.WuQuant = wuQuant_1.WuQuant; exports.WuColorCube = wuQuant_1.WuColorCube; /***/ }, /* 21 */ /***/ function(module, exports, __webpack_require__) { /* * NeuQuant Neural-Net Quantization Algorithm * ------------------------------------------ * * Copyright (c) 1994 Anthony Dekker * * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. See * "Kohonen neural networks for optimal colour quantization" in "Network: * Computation in Neural Systems" Vol. 5 (1994) pp 351-367. for a discussion of * the algorithm. * * Any party obtaining a copy of these files from the author, directly or * indirectly, is granted, free of charge, a full and unrestricted irrevocable, * world-wide, paid up, royalty-free, nonexclusive right and license to deal in * this software and documentation files (the "Software"), including without * limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons who * receive copies from any such party to do so, with the only requirement being * that this copyright notice remain intact. */ "use strict"; /** * @preserve TypeScript port: * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * neuquant.ts - part of Image Quantization Library */ var palette_1 = __webpack_require__(22); var point_1 = __webpack_require__(24); // bias for colour values var networkBiasShift = 3; var Neuron = (function () { function Neuron(defaultValue) { this.r = this.g = this.b = this.a = defaultValue; } /** * There is a fix in original NEUQUANT by Anthony Dekker (http://members.ozemail.com.au/~dekker/NEUQUANT.HTML) * @example * r = Math.min(255, (neuron.r + (1 << (networkBiasShift - 1))) >> networkBiasShift); */ Neuron.prototype.toPoint = function () { return point_1.Point.createByRGBA(this.r >> networkBiasShift, this.g >> networkBiasShift, this.b >> networkBiasShift, this.a >> networkBiasShift); }; Neuron.prototype.subtract = function (r, g, b, a) { this.r -= r | 0; this.g -= g | 0; this.b -= b | 0; this.a -= a | 0; }; return Neuron; }()); var NeuQuant = (function () { function NeuQuant(colorDistanceCalculator, colors) { if (colors === void 0) { colors = 256; } this._distance = colorDistanceCalculator; this._pointArray = []; this._sampleFactor = 1; this._networkSize = colors; this._distance.setWhitePoint(255 << networkBiasShift, 255 << networkBiasShift, 255 << networkBiasShift, 255 << networkBiasShift); } NeuQuant.prototype.sample = function (pointBuffer) { this._pointArray = this._pointArray.concat(pointBuffer.getPointArray()); }; NeuQuant.prototype.quantize = function () { this._init(); this._learn(); return this._buildPalette(); }; NeuQuant.prototype._init = function () { this._freq = []; this._bias = []; this._radPower = []; this._network = []; for (var i = 0; i < this._networkSize; i++) { this._network[i] = new Neuron((i << (networkBiasShift + 8)) / this._networkSize | 0); // 1/this._networkSize this._freq[i] = NeuQuant._initialBias / this._networkSize | 0; this._bias[i] = 0; } }; /** * Main Learning Loop */ NeuQuant.prototype._learn = function () { var sampleFactor = this._sampleFactor; var pointsNumber = this._pointArray.length; if (pointsNumber < NeuQuant._minpicturebytes) sampleFactor = 1; var alphadec = 30 + (sampleFactor - 1) / 3 | 0, pointsToSample = pointsNumber / sampleFactor | 0; var delta = pointsToSample / NeuQuant._nCycles | 0, alpha = NeuQuant._initAlpha, radius = (this._networkSize >> 3) * NeuQuant._radiusBias; var rad = radius >> NeuQuant._radiusBiasShift; if (rad <= 1) rad = 0; for (var i = 0; i < rad; i++) { this._radPower[i] = alpha * (((rad * rad - i * i) * NeuQuant._radBias) / (rad * rad)) >>> 0; } var step; if (pointsNumber < NeuQuant._minpicturebytes) { step = 1; } else if (pointsNumber % NeuQuant._prime1 != 0) { step = NeuQuant._prime1; } else if ((pointsNumber % NeuQuant._prime2) != 0) { step = NeuQuant._prime2; } else if ((pointsNumber % NeuQuant._prime3) != 0) { step = NeuQuant._prime3; } else { step = NeuQuant._prime4; } for (var i = 0, pointIndex = 0; i < pointsToSample;) { var point = this._pointArray[pointIndex], b = point.b << networkBiasShift, g = point.g << networkBiasShift, r = point.r << networkBiasShift, a = point.a << networkBiasShift, neuronIndex = this._contest(b, g, r, a); this._alterSingle(alpha, neuronIndex, b, g, r, a); if (rad !== 0) this._alterNeighbour(rad, neuronIndex, b, g, r, a); /* alter neighbours */ pointIndex += step; if (pointIndex >= pointsNumber) pointIndex -= pointsNumber; i++; if (delta === 0) delta = 1; if (i % delta === 0) { alpha -= (alpha / alphadec) | 0; radius -= (radius / NeuQuant._radiusDecrease) | 0; rad = radius >> NeuQuant._radiusBiasShift; if (rad <= 1) rad = 0; for (var j = 0; j < rad; j++) this._radPower[j] = alpha * (((rad * rad - j * j) * NeuQuant._radBias) / (rad * rad)) >>> 0; } } }; NeuQuant.prototype._buildPalette = function () { var palette = new palette_1.Palette(); this._network.forEach(function (neuron) { palette.add(neuron.toPoint()); }); palette.sort(); return palette; }; /** * Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|] */ NeuQuant.prototype._alterNeighbour = function (rad, i, b, g, r, al) { var lo = i - rad; if (lo < -1) lo = -1; var hi = i + rad; if (hi > this._networkSize) hi = this._networkSize; var j = i + 1, k = i - 1, m = 1; while (j < hi || k > lo) { var a = this._radPower[m++] / NeuQuant._alphaRadBias; if (j < hi) { var p = this._network[j++]; p.subtract(a * (p.r - r), a * (p.g - g), a * (p.b - b), a * (p.a - al)); } if (k > lo) { var p = this._network[k--]; p.subtract(a * (p.r - r), a * (p.g - g), a * (p.b - b), a * (p.a - al)); } } }; /** * Move neuron i towards biased (b,g,r) by factor alpha */ NeuQuant.prototype._alterSingle = function (alpha, i, b, g, r, a) { alpha /= NeuQuant._initAlpha; /* alter hit neuron */ var n = this._network[i]; n.subtract(alpha * (n.r - r), alpha * (n.g - g), alpha * (n.b - b), alpha * (n.a - a)); }; /** * Search for biased BGR values * description: * finds closest neuron (min dist) and updates freq * finds best neuron (min dist-bias) and returns position * for frequently chosen neurons, freq[i] is high and bias[i] is negative * bias[i] = _gamma*((1/this._networkSize)-freq[i]) * * Original distance equation: * dist = abs(dR) + abs(dG) + abs(dB) */ NeuQuant.prototype._contest = function (b, g, r, a) { var multiplier = (255 * 4) << networkBiasShift; var bestd = ~(1 << 31), bestbiasd = bestd, bestpos = -1, bestbiaspos = bestpos; for (var i = 0; i < this._networkSize; i++) { var n = this._network[i], dist = this._distance.calculateNormalized(n, { r: r, g: g, b: b, a: a }) * multiplier | 0; if (dist < bestd) { bestd = dist; bestpos = i; } var biasdist = dist - ((this._bias[i]) >> (NeuQuant._initialBiasShift - networkBiasShift)); if (biasdist < bestbiasd) { bestbiasd = biasdist; bestbiaspos = i; } var betafreq = (this._freq[i] >> NeuQuant._betaShift); this._freq[i] -= betafreq; this._bias[i] += (betafreq << NeuQuant._gammaShift); } this._freq[bestpos] += NeuQuant._beta; this._bias[bestpos] -= NeuQuant._betaGamma; return bestbiaspos; }; /* four primes near 500 - assume no image has a length so large that it is divisible by all four primes */ NeuQuant._prime1 = 499; NeuQuant._prime2 = 491; NeuQuant._prime3 = 487; NeuQuant._prime4 = 503; NeuQuant._minpicturebytes = NeuQuant._prime4; // no. of learning cycles NeuQuant._nCycles = 100; // defs for freq and bias NeuQuant._initialBiasShift = 16; // bias for fractions NeuQuant._initialBias = (1 << NeuQuant._initialBiasShift); NeuQuant._gammaShift = 10; // gamma = 1024 // TODO: why gamma is never used? //private static _gamma : number = (1 << NeuQuant._gammaShift); NeuQuant._betaShift = 10; NeuQuant._beta = (NeuQuant._initialBias >> NeuQuant._betaShift); // beta = 1/1024 NeuQuant._betaGamma = (NeuQuant._initialBias << (NeuQuant._gammaShift - NeuQuant._betaShift)); /* * for 256 cols, radius starts */ NeuQuant._radiusBiasShift = 6; // at 32.0 biased by 6 bits NeuQuant._radiusBias = 1 << NeuQuant._radiusBiasShift; // and decreases by a factor of 1/30 each cycle NeuQuant._radiusDecrease = 30; /* defs for decreasing alpha factor */ // alpha starts at 1.0 NeuQuant._alphaBiasShift = 10; // biased by 10 bits NeuQuant._initAlpha = (1 << NeuQuant._alphaBiasShift); /* radBias and alphaRadBias used for radpower calculation */ NeuQuant._radBiasShift = 8; NeuQuant._radBias = 1 << NeuQuant._radBiasShift; NeuQuant._alphaRadBiasShift = NeuQuant._alphaBiasShift + NeuQuant._radBiasShift; NeuQuant._alphaRadBias = 1 << NeuQuant._alphaRadBiasShift; return NeuQuant; }()); exports.NeuQuant = NeuQuant; /***/ }, /* 22 */ /***/ function(module, exports, __webpack_require__) { /** * @preserve * Copyright 2015-2016 Igor Bezkrovnyi * All rights reserved. (MIT Licensed) * * palette.ts - part of Image Quantization Library */ "use strict"; var pointContainer_1 = __webpack_require__(23); var rgb2hsl_1 = __webpack_require__(5); // TODO: make paletteArray via pointBuffer, so, export will be available via pointBuffer.exportXXX var hueGroups = 10; function hueGroup(hue, segmentsNumber) { var maxHue = 360, seg = maxHue / segmentsNumber, half = seg / 2; for (var i = 1, mid = seg - half; i < segmentsNumber; i++, mid += seg) { if (hue >= mid && hue < mid + seg) return i; } return 0; } exports.hueGroup = hueGroup; var Palette = (function () { function Palette() { this._pointArray = []; this._i32idx = {}; this._pointContainer = new pointContainer_1.PointContainer(); this._pointContainer.setHeight(1); this._pointArray = this._pointContainer.getPointArray(); } Palette.prototype.add = function (color) { this._pointArray.push(color); this._pointContainer.setWidth(this._pointArray.length); }; Palette.prototype.has = function (color) { for (var i = this._pointArray.length - 1; i >= 0; i--) { if (color.uint32 === this._pointArray[i].uint32) return true; } return false; }; // TOTRY: use HUSL - http://boronine.com/husl/ http://www.husl-colors.org/ https://github.com/husl-colors/husl Palette.prototype.getNearestColor = function (colorDistanceCalculator, color) { return this._pointArray[this.getNearestIndex(colorDistanceCalculator, color) | 0]; }; Palette.prototype.getPointContainer = function () { return this._pointContainer; }; // TOTRY: use HUSL - http://boronine.com/husl/ /* public nearestIndexByUint32(i32) { var idx : number = this._nearestPointFromCache("" + i32); if (idx >= 0) return idx; var min = 1000, rgb = [ (i32 & 0xff), (i32 >>> 8) & 0xff, (i32 >>> 16) & 0xff, (i32 >>> 24) & 0xff ], len = this._pointArray.length; idx = 0; for (var i = 0; i < len; i++) { var dist = Utils.distEuclidean(rgb, this._pointArray[i].rgba); if (dist < min) { min = dist; idx = i; } } this._i32idx[i32] = idx; return idx; } */ Palette.prototype._nearestPointFromCache = function (key) { return typeof this._i32idx[key] === "number" ? this._i32idx[key] : -1; }; Palette.prototype.getNearestIndex = function (colorDistanceCalculator, point) { var idx = this._nearestPointFromCache("" + point.uint32); if (idx >= 0) return idx; var minimalDistance = Number.MAX_VALUE; idx = 0; for (var i = 0, l = this._pointArray.length; i < l; i++) { var p = this._pointArray[i], distance = colorDistanceCalculator.calculateRaw(point.r, point.g, point.b, point.a, p.r, p.g, p.b, p.a); if (distance < minimalDistance) { minimalDistance = distance; idx = i; } } this._i32idx[point.uint32] = idx; return idx; }; /* public reduce(histogram : ColorHistogram, colors : number) { if (this._pointArray.length > colors) { var idxi32 = histogram.getImportanceSortedColorsIDXI32(); // quantize histogram to existing palette var keep = [], uniqueColors = 0, idx, pruned = false; for (var i = 0, len = idxi32.length; i < len; i++) { // palette length reached, unset all remaining colors (sparse palette) if (uniqueColors >= colors) { this.prunePal(keep); pruned = true; break; } else { idx = this.nearestIndexByUint32(idxi32[i]); if (keep.indexOf(idx) < 0) { keep.push(idx); uniqueColors++; } } } if (!pruned) { this.prunePal(keep); } } } // TODO: check usage, not tested! public prunePal(keep : number[]) { var colors = this._pointArray.length; for (var colorIndex = colors - 1; colorIndex >= 0; colorIndex--) { if (keep.indexOf(colorIndex) < 0) { if(colorIndex + 1 < colors) { this._pointArray[ colorIndex ] = this._pointArray [ colors - 1 ]; } --colors; //this._pointArray[colorIndex] = null; } } console.log("colors pruned: " + (this._pointArray.length - colors)); this._pointArray.length = colors; this._i32idx = {}; } */ // TODO: group very low lum and very high lum colors // TODO: pass custom sort order // TODO: sort criteria function should be placed to HueStats class Palette.prototype.sort = function () { this._i32idx = {}; this._pointArray.sort(function (a, b) { var hslA = rgb2hsl_1.rgb2hsl(a.r, a.g, a.b), hslB = rgb2hsl_1.rgb2hsl(b.r, b.g, b.b); // sort all grays + whites together var hueA = (a