public ditherRiemer(pointBuffer : PointContainer, palette : Palette) : PointContainer {
	var pointArray = pointBuffer.getPointArray(),
		width = pointBuffer.getWidth(),
		height = pointBuffer.getHeight(),
		errorArray = [],
		weightsArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32];

	var sum = 0;
	for(var i = 0; i < weightsArray.length; i++) {
		sum += weightsArray[i];
	}
	for(var i = 0; i < weightsArray.length; i++) {
		weightsArray[i] /= sum;
	}

	for(var i = 0; i < 4; i++) {
		errorArray[i] = [];
		for(var j = 0; j < weightsArray.length; j++) {
			errorArray[i].push(0);
		}
	}

	function simpleCurve(width, height, callback : (x : number, y : number, index : number) => void) {
		for (var y = 0, index = 0; y < height; y++) {
			for (var x = 0; x < width; x++, index++) {
				callback(x, y, index);
			}

		}
	}

	simpleCurve(width, height, (x, y, index) => {
		var p = pointArray[ index];

		for(var quadrupletIndex = 0; quadrupletIndex < errorArray.length; quadrupletIndex++) {
			var sum = 0;
			for(var errorArrayIndex = 0; errorArrayIndex < errorArray.length; errorArrayIndex++) {
				sum += errorArray[quadrupletIndex][errorArrayIndex] * weightsArray[errorArrayIndex];
			}

			p.rgba[quadrupletIndex] = Math.max(0, Math.min(255, (p.rgba[quadrupletIndex] + sum) | 0));
		}

		var correctedPoint = Point.createByQuadruplet(p.rgba),
			palettePoint = palette.nearestColor(correctedPoint);

		for(var quadrupletIndex = 0; quadrupletIndex < errorArray.length; quadrupletIndex++) {
			var componentErrorArray = errorArray[quadrupletIndex];
			componentErrorArray.shift();
			componentErrorArray.push(p.rgba[quadrupletIndex] - palettePoint.rgba[quadrupletIndex]);
		}

		p.from(palettePoint);
	});
	return pointBuffer;
}
