// ==UserScript==
// @version 1.0
// @author Leon Sorokin
// @license MIT
// ==/UserScript==
/*
* Copyright (c) 2015, Leon Sorokin
* All rights reserved. (MIT Licensed)
*
* RgbQuant.js - an image quantization lib
*/
(function(){function t(t){if(t=t||{},this.method=t.method||2,this.colors=t.colors||256,this.initColors=t.initColors||4096,this.initDist=t.initDist||.01,this.distIncr=t.distIncr||.005,this.hueGroups=t.hueGroups||10,this.satGroups=t.satGroups||10,this.lumGroups=t.lumGroups||10,this.minHueCols=t.minHueCols||0,this.hueStats=this.minHueCols?new i(this.hueGroups,this.minHueCols):null,this.boxSize=t.boxSize||[64,64],this.boxPxls=t.boxPxls||2,this.palLocked=!1,this.dithKern=t.dithKern||null,this.dithSerp=t.dithSerp||!1,this.dithDelta=t.dithDelta||0,this.histogram={},this.idxrgb=t.palette?t.palette.slice(0):[],this.idxi32=[],this.i32idx={},this.i32rgb={},this.useCache=!1!==t.useCache,this.cacheFreq=t.cacheFreq||10,this.reIndex=t.reIndex||0==this.idxrgb.length,this.colorDist="manhattan"==t.colorDist?u:a,this.idxrgb.length>0){var r=this;this.idxrgb.forEach(function(t,i){var s=(255<<24|t[2]<<16|t[1]<<8|t[0])>>>0;r.idxi32[i]=s,r.i32idx[s]=i,r.i32rgb[s]=t})}}function i(t,i){this.numGroups=t,this.minCols=i,this.stats={};for(var r=-1;r<t;r++)this.stats[r]={num:0,cols:[]};this.groupsFull=0}t.prototype.sample=function(t,i){if(this.palLocked)throw"Cannot sample additional images, palette already assembled.";var r=v(t,i);switch(this.method){case 1:this.colorStats1D(r.buf32);break;case 2:this.colorStats2D(r.buf32,r.width)}},t.prototype.reduce=function(t,i,r,s){if(this.palLocked||this.buildPal(),r=r||this.dithKern,s=void 0!==s?s:this.dithSerp,i=i||1,r)var e=this.dither(t,r,s);else for(var h=v(t).buf32,n=h.length,a=(e=new Uint32Array(n),0);a<n;a++){var o=h[a];e[a]=this.nearestColor(o)}if(1==i)return new Uint8Array(e.buffer);if(2==i){var u=[];for(n=e.length,a=0;a<n;a++){o=e[a];u[a]=this.i32idx[o]}return u}},t.prototype.dither=function(t,i,r){var s={FloydSteinberg:[[7/16,1,0],[3/16,-1,1],[5/16,0,1],[1/16,1,1]],FalseFloydSteinberg:[[3/8,1,0],[3/8,0,1],[.25,1,1]],Stucki:[[8/42,1,0],[4/42,2,0],[2/42,-2,1],[4/42,-1,1],[8/42,0,1],[4/42,1,1],[2/42,2,1],[1/42,-2,2],[2/42,-1,2],[4/42,0,2],[2/42,1,2],[1/42,2,2]],Atkinson:[[1/8,1,0],[1/8,2,0],[1/8,-1,1],[1/8,0,1],[1/8,1,1],[1/8,0,2]],Jarvis:[[7/48,1,0],[5/48,2,0],[3/48,-2,1],[5/48,-1,1],[7/48,0,1],[5/48,1,1],[3/48,2,1],[1/48,-2,2],[3/48,-1,2],[5/48,0,2],[3/48,1,2],[1/48,2,2]],Burkes:[[.25,1,0],[.125,2,0],[2/32,-2,1],[.125,-1,1],[.25,0,1],[.125,1,1],[2/32,2,1]],Sierra:[[5/32,1,0],[3/32,2,0],[2/32,-2,1],[.125,-1,1],[5/32,0,1],[.125,1,1],[2/32,2,1],[2/32,-1,2],[3/32,0,2],[2/32,1,2]],TwoSierra:[[.25,1,0],[3/16,2,0],[1/16,-2,1],[.125,-1,1],[3/16,0,1],[.125,1,1],[1/16,2,1]],SierraLite:[[.5,1,0],[.25,-1,1],[.25,0,1]]};if(!i||!s[i])throw"Unknown dithering kernel: "+i;for(var e=s[i],h=v(t),n=h.buf32,a=h.width,o=h.height,u=(n.length,r?-1:1),l=0;l<o;l++){r&&(u*=-1);for(var c=l*a,d=1==u?0:a-1,f=1==u?a:0;d!==f;d+=u){var x=c+d,p=n[x],g=255&p,b=(65280&p)>>8,m=(16711680&p)>>16,y=this.nearestColor(p),w=255&y,S=(65280&y)>>8,C=(16711680&y)>>16;if(n[x]=255<<24|C<<16|S<<8|w,this.dithDelta)if(this.colorDist([g,b,m],[w,S,C])<this.dithDelta)continue;for(var k=g-w,D=b-S,M=m-C,A=1==u?0:e.length-1,I=1==u?e.length:0;A!==I;A+=u){var P=e[A][1]*u,F=e[A][2],G=F*a;if(P+d>=0&&P+d<a&&F+l>=0&&F+l<o){var U=e[A][0],H=x+(G+P),j=255&n[H],q=(65280&n[H])>>8,E=(16711680&n[H])>>16,L=Math.max(0,Math.min(255,j+k*U)),O=Math.max(0,Math.min(255,q+D*U)),z=Math.max(0,Math.min(255,E+M*U));n[H]=255<<24|z<<16|O<<8|L}}}}return n},t.prototype.buildPal=function(t){if(!(this.palLocked||this.idxrgb.length>0&&this.idxrgb.length<=this.colors)){var i=this.histogram,r=function(t,i){var r=[];for(var s in t)r.push(s);return g.call(r,function(r,s){return i?t[s]-t[r]:t[r]-t[s]})}(i,!0);if(0==r.length)throw"Nothing has been sampled, palette cannot be built.";switch(this.method){case 1:for(var s=this.initColors,e=i[r[s-1]],h=r.slice(0,s),n=s,a=r.length;n<a&&i[r[n]]==e;)h.push(r[n++]);this.hueStats&&this.hueStats.inject(h);break;case 2:h=r}h=h.map(function(t){return+t}),this.reducePal(h),!t&&this.reIndex&&this.sortPal(),this.useCache&&this.cacheHistogram(h),this.palLocked=!0}},t.prototype.palette=function(t,i){return this.buildPal(i),t?this.idxrgb:new Uint8Array(new Uint32Array(this.idxi32).buffer)},t.prototype.prunePal=function(t){for(var i,r=0;r<this.idxrgb.length;r++)t[r]||(i=this.idxi32[r],this.idxrgb[r]=null,this.idxi32[r]=null,delete this.i32idx[i]);if(this.reIndex){for(var s=[],e=[],h={},n=(r=0,0);r<this.idxrgb.length;r++)this.idxrgb[r]&&(i=this.idxi32[r],s[n]=this.idxrgb[r],h[i]=n,e[n]=i,n++);this.idxrgb=s,this.idxi32=e,this.i32idx=h}},t.prototype.reducePal=function(t){if(this.idxrgb.length>this.colors){for(var i,r=t.length,s={},e=0,h=!1,n=0;n<r;n++)e!=this.colors||h||(this.prunePal(s),h=!0),i=this.nearestIndex(t[n]),e<this.colors&&!s[i]&&(s[i]=!0,e++);h||(this.prunePal(s),h=!0)}else{var a=t.map(function(t){return[255&t,(65280&t)>>8,(16711680&t)>>16]}),o=r=a.length,u=this.initDist;if(o>this.colors){for(;o>this.colors;){var l=[];for(n=0;n<r;n++){var c=a[n];t[n];if(c)for(var d=n+1;d<r;d++){var f=a[d],x=t[d];if(f){var p=this.colorDist(c,f);p<u&&(l.push([d,f,x,p]),delete a[d],o--)}}}u+=o>3*this.colors?this.initDist:this.distIncr}if(o<this.colors){g.call(l,function(t,i){return i[3]-t[3]});for(var v=0;o<this.colors;)a[l[v][0]]=l[v][1],o++,v++}}for(r=a.length,n=0;n<r;n++)a[n]&&(this.idxrgb.push(a[n]),this.idxi32.push(t[n]),this.i32idx[t[n]]=this.idxi32.length-1,this.i32rgb[t[n]]=a[n])}},t.prototype.colorStats1D=function(t){for(var i,r=this.histogram,s=t.length,e=0;e<s;e++)(4278190080&(i=t[e]))>>24!=0&&(this.hueStats&&this.hueStats.check(i),i in r?r[i]++:r[i]=1)},t.prototype.colorStats2D=function(t,i){var r=this.boxSize[0],s=this.boxSize[1],e=r*s,h=function(t,i,r,s){for(var e=t%r,h=i%s,n=t-e,a=i-h,o=[],u=0;u<i;u+=s)for(var l=0;l<t;l+=r)o.push({x:l,y:u,w:l==n?e:r,h:u==a?h:s});return o}(i,t.length/i,r,s),n=this.histogram,a=this;h.forEach(function(r){var s,h=Math.max(Math.round(r.w*r.h/e)*a.boxPxls,2),o={};!function(t,i,r){var s=t,e=s.y*i+s.x,h=(s.y+s.h-1)*i+(s.x+s.w-1),n=0,a=i-s.w+1,o=e;do{r.call(this,o),o+=++n%s.w==0?a:1}while(o<=h)}(r,i,function(i){(4278190080&(s=t[i]))>>24!=0&&(a.hueStats&&a.hueStats.check(s),s in n?n[s]++:s in o?++o[s]>=h&&(n[s]=o[s]):o[s]=1)})}),this.hueStats&&this.hueStats.inject(n)},t.prototype.sortPal=function(){var t=this;this.idxi32.sort(function(i,r){var s=t.i32idx[i],e=t.i32idx[r],h=t.idxrgb[s],n=t.idxrgb[e],a=l(h[0],h[1],h[2]),o=l(n[0],n[1],n[2]),u=h[0]==h[1]&&h[1]==h[2]?-1:c(a.h,t.hueGroups),x=(n[0]==n[1]&&n[1]==n[2]?-1:c(o.h,t.hueGroups))-u;if(x)return-x;var p=f(+o.l.toFixed(2))-f(+a.l.toFixed(2));if(p)return-p;var g=d(+o.s.toFixed(2))-d(+a.s.toFixed(2));return g?-g:void 0}),this.idxi32.forEach(function(i,r){t.idxrgb[r]=t.i32rgb[i],t.i32idx[i]=r})},t.prototype.nearestColor=function(t){var i=this.nearestIndex(t);return null===i?0:this.idxi32[i]},t.prototype.nearestIndex=function(t){if((4278190080&t)>>24==0)return null;if(this.useCache&&""+t in this.i32idx)return this.i32idx[t];for(var i,r=1e3,s=[255&t,(65280&t)>>8,(16711680&t)>>16],e=this.idxrgb.length,h=0;h<e;h++)if(this.idxrgb[h]){var n=this.colorDist(s,this.idxrgb[h]);n<r&&(r=n,i=h)}return i},t.prototype.cacheHistogram=function(t){for(var i=0,r=t[i];i<t.length&&this.histogram[r]>=this.cacheFreq;r=t[i++])this.i32idx[r]=this.nearestIndex(r)},i.prototype.check=function(t){this.groupsFull==this.numGroups+1&&(this.check=function(){});var i=255&t,r=(65280&t)>>8,s=(16711680&t)>>16,e=i==r&&r==s?-1:c(l(i,r,s).h,this.numGroups),h=this.stats[e],n=this.minCols;h.num++,h.num>n||(h.num==n&&this.groupsFull++,h.num<=n&&this.stats[e].cols.push(t))},i.prototype.inject=function(t){for(var i=-1;i<this.numGroups;i++)if(this.stats[i].num<=this.minCols)switch(x(t)){case"Array":this.stats[i].cols.forEach(function(i){-1==t.indexOf(i)&&t.push(i)});break;case"Object":this.stats[i].cols.forEach(function(i){t[i]?t[i]++:t[i]=1})}};var r=.2126,s=.7152,e=.0722;function h(t,i,h){return Math.sqrt(r*t*t+s*i*i+e*h*h)}var n=Math.sqrt(255*r*255+255*s*255+255*e*255);function a(t,i){var h=i[0]-t[0],a=i[1]-t[1],o=i[2]-t[2];return Math.sqrt(r*h*h+s*a*a+e*o*o)/n}var o=255*r+255*s+255*e;function u(t,i){var h=Math.abs(i[0]-t[0]),n=Math.abs(i[1]-t[1]),a=Math.abs(i[2]-t[2]);return(r*h+s*n+e*a)/o}function l(t,i,r){var s,e,n,a,o;if(t/=255,i/=255,r/=255,(s=Math.max(t,i,r))==(e=Math.min(t,i,r)))n=a=0;else{switch(o=s-e,a=(s+e)/2>.5?o/(2-s-e):o/(s+e),s){case t:n=(i-r)/o+(i<r?6:0);break;case i:n=(r-t)/o+2;break;case r:n=(t-i)/o+4}n/=6}return{h:n,s:a,l:h(t,i,r)}}function c(t,i){var r=1/i,s=r/2;if(t>=1-s||t<=s)return 0;for(var e=1;e<i;e++){var h=e*r;if(t>=h-s&&t<=h+s)return e}}function d(t){return t}function f(t){return t}function x(t){return Object.prototype.toString.call(t).slice(8,-1)}var p,g="xyzvwtursopqmnklhijfgdeabc"==(p="abcdefghijklmnopqrstuvwxyz").split("").sort(function(t,i){return~~(p.indexOf(i)/2.3)-~~(p.indexOf(t)/2.3)}).join("")?Array.prototype.sort:function(t){var i=x(this[0]);if("Number"==i||"String"==i){for(var r,s={},e=this.length,h=0;h<e;h++)r=this[h],s[r]||0===s[r]||(s[r]=h);return this.sort(function(i,r){return t(i,r)||s[i]-s[r]})}var s=this.map(function(t){return t});return this.sort(function(i,r){return t(i,r)||s.indexOf(i)-s.indexOf(r)})};function v(t,i){var r,s,e,h,n,a;switch(x(t)){case"HTMLImageElement":(r=document.createElement("canvas")).width=t.naturalWidth,r.height=t.naturalHeight,(s=r.getContext("2d")).drawImage(t,0,0);case"Canvas":case"HTMLCanvasElement":r=r||t,s=s||r.getContext("2d");case"CanvasRenderingContext2D":s=s||t,r=r||s.canvas,e=s.getImageData(0,0,r.width,r.height);case"ImageData":i=(e=e||t).width,h="CanvasPixelArray"==x(e.data)?new Uint8Array(e.data):e.data;case"Array":case"CanvasPixelArray":h=h||new Uint8Array(t);case"Uint8Array":case"Uint8ClampedArray":h=h||t,n=new Uint32Array(h.buffer);case"Uint32Array":n=n||t,h=h||new Uint8Array(n.buffer),i=i||n.length,a=n.length/i}return{can:r,ctx:s,imgd:e,buf8:h,buf32:n,width:i,height:a}}this.RgbQuant=t,"undefined"!=typeof module&&module.exports&&(module.exports=t)}).call(this);