UNPKG

webdriverio-automation

Version:

WebdriverIO-Automation android ios project

113 lines (96 loc) 4.87 kB
/** * @preserve * MIT License * * Copyright 2015-2016 Igor Bezkrovnyi * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * nearestColor.ts - part of Image Quantization Library */ import { IImageDitherer } from "./common" import { HilbertCurveBase } from "./spaceFillingCurves/hilbertCurve" import { AbstractDistanceCalculator } from "../distance/abstractDistanceCalculator" import { PointContainer } from "../utils/pointContainer" import { Palette } from "../utils/palette" import { Point } from "../utils/point" import { inRange0to255Rounded } from "../utils/arithmetic" export class ErrorDiffusionRiemersma implements IImageDitherer { private _distance : AbstractDistanceCalculator; private _weights : number[]; private _errorQueueSize : number; private _errorPropagation : number; private _max : number; constructor(colorDistanceCalculator : AbstractDistanceCalculator, errorQueueSize : number = 16, errorPropagation : number = 1) { this._distance = colorDistanceCalculator; this._errorPropagation = errorPropagation; this._errorQueueSize = errorQueueSize; this._max = this._errorQueueSize; this._createWeights(); } quantize(pointBuffer : PointContainer, palette : Palette) : PointContainer { const curve = new HilbertCurveBase(), pointArray = pointBuffer.getPointArray(), width = pointBuffer.getWidth(), height = pointBuffer.getHeight(), errorQueue : {r : number; g : number; b : number; a : number}[] = []; let head = 0; for (let i = 0; i < this._errorQueueSize; i++) { errorQueue[ i ] = { r : 0, g : 0, b : 0, a : 0 }; } curve.walk(width, height, (x, y) => { const p = pointArray[ x + y * width ]; let r = p.r, g = p.g, b = p.b, a = p.a; for (let i = 0; i < this._errorQueueSize; i++) { const weight = this._weights[ i ], e = errorQueue[ (i + head) % this._errorQueueSize ]; r += e.r * weight; g += e.g * weight; b += e.b * weight; a += e.a * weight; } const correctedPoint = Point.createByRGBA( inRange0to255Rounded(r), inRange0to255Rounded(g), inRange0to255Rounded(b), inRange0to255Rounded(a) ); const quantizedPoint = palette.getNearestColor(this._distance, correctedPoint); // update head and calculate tail head = (head + 1) % this._errorQueueSize; const tail = (head + this._errorQueueSize - 1) % this._errorQueueSize; // update error with new value errorQueue[ tail ].r = p.r - quantizedPoint.r; errorQueue[ tail ].g = p.g - quantizedPoint.g; errorQueue[ tail ].b = p.b - quantizedPoint.b; errorQueue[ tail ].a = p.a - quantizedPoint.a; // update point p.from(quantizedPoint); }); return pointBuffer; } private _createWeights() : void { this._weights = []; const multiplier = Math.exp(Math.log(this._max) / (this._errorQueueSize - 1)); for (let i = 0, next = 1; i < this._errorQueueSize; i++) { this._weights[ i ] = (((next + 0.5) | 0) / this._max) * this._errorPropagation; next *= multiplier; } } }