mirror of
https://github.com/kkapsner/CanvasBlocker
synced 2025-01-03 10:31:54 +01:00
Added setting "ignoreFrequentColors"
This commit is contained in:
parent
9da251b14d
commit
1733be23f2
@ -184,6 +184,15 @@
|
||||
"description": ""
|
||||
},
|
||||
|
||||
"ignoreFrequentColors_title": {
|
||||
"message": "Ignoriere die häufigsten Farben",
|
||||
"description": ""
|
||||
},
|
||||
"ignoreFrequentColors_description": {
|
||||
"message": "Anzahl der Farben, die pro Canvas nicht vorgetäuscht werden sollen. Dies ist ein Parameter, der die Detektion des Addons erschweren soll.\nACHTUNG: Dies kann die Geschwindigkeit des Addons beeinträchtigen, da für jedes Bild die Farbstatistik berechnet werden muss. Außerdem kann es die Sicherheit des Addons verringern, wenn der Wert zu hoch gestellt wird. Deswegen wird stark empfohlen, diesen Wert nicht über 3 zu setzen.",
|
||||
"description": ""
|
||||
},
|
||||
|
||||
"disableNotifications": {
|
||||
"message": "Benachrichtigungen deaktivieren",
|
||||
"description": ""
|
||||
|
@ -184,6 +184,15 @@
|
||||
"description": ""
|
||||
},
|
||||
|
||||
"ignoreFrequentColors_title": {
|
||||
"message": "Ignore the most frequent colors",
|
||||
"description": ""
|
||||
},
|
||||
"ignoreFrequentColors_description": {
|
||||
"message": "Number of colors that should not be faked per canvas. This is a parameter to prevent detection.\nCAUTION: This can reduce the performance of the addon because the color statistic has to be calculated for every image. Additional this can lower the safety of the addon, therefore it is highly recommended not to set this value above 3.",
|
||||
"description": ""
|
||||
},
|
||||
|
||||
"disableNotifications": {
|
||||
"message": "disable notifications",
|
||||
"description": ""
|
||||
|
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(
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
"lib/logging.js",
|
||||
|
||||
"lib/colorStatistics.js",
|
||||
"lib/modifiedAPI.js",
|
||||
"lib/randomSupplies.js",
|
||||
"lib/intercept.js",
|
||||
|
@ -130,6 +130,15 @@ document.body.appendChild(table);
|
||||
"rng": ["persistent"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ignoreFrequentColors",
|
||||
"title": "Ignore most frequent colors",
|
||||
"type": "integer",
|
||||
"value": 0,
|
||||
"displayDependencies": {
|
||||
"blockMode": ["fakeReadout"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "askOnlyOnce",
|
||||
"title": "Ask only once",
|
||||
|
@ -6,6 +6,7 @@ Version 0.4.0:
|
||||
- switched to webExtension
|
||||
- notifications are now done via page action
|
||||
- minimal and maximal fake size are now respected in all fakeable functions
|
||||
- fake readout now fakes one pixel at once and no longer one single channel
|
||||
|
||||
new features:
|
||||
- information of all fake events in one tab are visible
|
||||
@ -13,6 +14,8 @@ Version 0.4.0:
|
||||
- new preferences:
|
||||
* minimal fake size
|
||||
* setting to enable the inspection of the content of the faked canvas
|
||||
* new random number generator "constant"
|
||||
* setting to not fake the most frequent colors in a canvas
|
||||
|
||||
fixes:
|
||||
- ask mode did not work for input types
|
||||
|
Loading…
x
Reference in New Issue
Block a user