mirror of
https://github.com/kkapsner/CanvasBlocker
synced 2025-07-04 12:36:37 +02:00
Added setting "ignoreFrequentColors"
This commit is contained in:
parent
9da251b14d
commit
1733be23f2
8 changed files with 131 additions and 7 deletions
80
lib/colorStatistics.js
Normal file
80
lib/colorStatistics.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* jslint moz: true */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
(function(){
|
||||
"use strict";
|
||||
|
||||
|
||||
var scope;
|
||||
if ((typeof exports) !== "undefined"){
|
||||
scope = exports;
|
||||
}
|
||||
else {
|
||||
window.scope.colorStatistics = {};
|
||||
scope = window.scope.colorStatistics;
|
||||
}
|
||||
|
||||
class Statistic{
|
||||
constructor(){
|
||||
this.colors = Object.create(null);
|
||||
this.numberOfColors = 0;
|
||||
|
||||
this.minBoundary = {count: Number.NEGATIVE_INFINITY};
|
||||
this.maxBoundary = {count: Number.POSITIVE_INFINITY, previousColor: this.minBoundary};
|
||||
this.minBoundary.nextColor = this.maxBoundary;
|
||||
}
|
||||
addColor(r, g, b, a){
|
||||
var index = String.fromCharCode(r, g, b, a);
|
||||
var color = this.colors[index];
|
||||
if (!color){
|
||||
color = {index, color: [r, g, b, a], count: 0, previousColor: this.minBoundary, nextColor: this.minBoundary.nextColor};
|
||||
this.numberOfColors += 1;
|
||||
this.minBoundary.nextColor = color;
|
||||
color.nextColor.previousColor = color;
|
||||
this.colors[index] = color;
|
||||
}
|
||||
color.count += 1;
|
||||
if (color.count > color.nextColor.count){
|
||||
// swap colors to remain in right order
|
||||
// a -> b -> c -> d becomes a -> c -> b -> d
|
||||
var a = color.previousColor;
|
||||
var b = color;
|
||||
var c = color.nextColor;
|
||||
var d = color.nextColor.nextColor;
|
||||
|
||||
a.nextColor = c;
|
||||
c.previousColor = a;
|
||||
|
||||
c.nextColor = b;
|
||||
b.previousColor = c;
|
||||
|
||||
b.nextColor = d;
|
||||
d.previousColor = b;
|
||||
}
|
||||
}
|
||||
getMaxColors(n){
|
||||
var n = Math.min(n, this.numberOfColors);
|
||||
var colors = Object.create(null);
|
||||
var current = this.maxBoundary;
|
||||
for (;n && current;n -= 1){
|
||||
current = current.previousColor;
|
||||
colors[current.index] = current;
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
}
|
||||
|
||||
scope.compute = function computeColorStatistics(rawData){
|
||||
var statistic = new Statistic();
|
||||
for (var i = 0, l = rawData.length; i < l; i += 4){
|
||||
statistic.addColor(
|
||||
rawData[i + 0],
|
||||
rawData[i + 1],
|
||||
rawData[i + 2],
|
||||
rawData[i + 3]
|
||||
);
|
||||
}
|
||||
return statistic;
|
||||
}
|
||||
}());
|
|
@ -8,6 +8,7 @@ var settings = {
|
|||
minFakeSize: 1,
|
||||
maxFakeSize: 0,
|
||||
rng: "constant",
|
||||
ignoreFrequentColors: 0,
|
||||
persistentRndStorage: "",
|
||||
storePersistentRnd: false,
|
||||
askOnlyOnce: true,
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
scope = window.scope.modifiedAPI;
|
||||
}
|
||||
|
||||
const colorStatistics = require("./colorStatistics");
|
||||
|
||||
// let Cu = require("chrome").Cu;
|
||||
|
||||
var randomSupply = null;
|
||||
|
@ -52,7 +54,7 @@
|
|||
};
|
||||
}
|
||||
|
||||
function getFakeCanvas(window, original){
|
||||
function getFakeCanvas(window, original, prefs){
|
||||
try {
|
||||
// original may not be a canvas -> we must not leak an error
|
||||
var context = getContext(window, original);
|
||||
|
@ -61,6 +63,11 @@
|
|||
var l = desc.length;
|
||||
|
||||
var ignoredColors = {};
|
||||
if (prefs("ignoreFrequentColors")){
|
||||
var statistic = colorStatistics.compute(source);
|
||||
ignoredColors = statistic.getMaxColors(prefs("ignoreFrequentColors"));
|
||||
}
|
||||
|
||||
var rng = randomSupply.getPixelRng(l, window, ignoredColors);
|
||||
|
||||
for (var i = 0; i < l; i += 4){
|
||||
|
@ -175,7 +182,7 @@
|
|||
return function toDataURL(){
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
notify.call(this, "fakedReadout");
|
||||
return original.apply(getFakeCanvas(window, this), window.Array.from(arguments));
|
||||
return original.apply(getFakeCanvas(window, this, prefs), window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
|
@ -201,7 +208,7 @@
|
|||
return function toBlob(callback){
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
notify.call(this, "fakedReadout");
|
||||
return original.apply(getFakeCanvas(window, this), window.Array.from(arguments));
|
||||
return original.apply(getFakeCanvas(window, this, prefs), window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
|
@ -228,7 +235,7 @@
|
|||
return function mozGetAsFile(callback){
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
notify.call(this, "fakedReadout");
|
||||
return original.apply(getFakeCanvas(window, this), window.Array.from(arguments));
|
||||
return original.apply(getFakeCanvas(window, this, prefs), window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
|
@ -257,11 +264,11 @@
|
|||
var fakeCanvas;
|
||||
var context = this;
|
||||
if (this && this.canvas) {
|
||||
fakeCanvas = getFakeCanvas(window, this.canvas);
|
||||
fakeCanvas = getFakeCanvas(window, this.canvas, prefs);
|
||||
}
|
||||
if (fakeCanvas && fakeCanvas !== this.canvas){
|
||||
context = window.HTMLCanvasElement.prototype.getContext.call(
|
||||
getFakeCanvas(window, this.canvas),
|
||||
fakeCanvas,
|
||||
"2d"
|
||||
);
|
||||
}
|
||||
|
@ -349,7 +356,12 @@
|
|||
var xPixels = pixels;
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
var l = xPixels.length;
|
||||
var rng = randomSupply.getPixelRng(l, window, {});
|
||||
var ignoredColors = {};
|
||||
if (prefs("ignoreFrequentColors")){
|
||||
var statistic = colorStatistics.compute(pixels);
|
||||
ignoredColors = statistic.getMaxColors(prefs("ignoreFrequentColors"));
|
||||
}
|
||||
var rng = randomSupply.getPixelRng(l, window, ignoredColors);
|
||||
|
||||
for (var i = 0; i < l; i += 4){
|
||||
var [r, g, b, a] = rng(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue