<?php

class Dither {
	function rgb($c)
	{
		return array(($c >> 16) & 0xFF, ($c >> 8) & 0xFF, $c & 0xFF);		
	}
	function colordiff($c1, $c2)
	{
		$q = $this->rgb($c1);
		$p = $this->rgb($c2);
		$n = 4;
		return pow(($q[0] - $p[0]), $n) + pow(($q[1] - $p[1]), $n) + pow(($q[2] - $p[2]), $n);		
	}
	function chooseColor($diffs)
	{
		if ($diffs[0] < $diffs[1] && $diffs[0] < $diffs[2])
			return 0;
		if ($diffs[1] < $diffs[0] && $diffs[1] < $diffs[2])
			return 1;
		return 2;
	}
	function ditherColor($diffs)
	{
		$diffs[0] = rand(0, $diffs[0]);
		$diffs[1] = rand(0, $diffs[1]);
		$diffs[2] = rand(0, $diffs[2]);
		if ($diffs[0] < $diffs[1] && $diffs[0] < $diffs[2])
			return 0;
		if ($diffs[1] < $diffs[0] && $diffs[1] < $diffs[2])
			return 1;
		return 2;		
	}
	function dither_kyt($img){
		$width = imagesx($img);
		$height = imagesy($img);
		
		//to rgb
		for($x=0; $x < $width; $x++){
			for($y=0; $y < $height; $y++){
				$img_arr[$x][$y] = imagecolorat($img, $x, $y);
			}
		}
		$output = imagecreatetruecolor($width, $height);
		$cl[0] = imagecolorallocate($output, 0, 0, 0); //background color.
		$cl[1] = imagecolorallocate($output, 0xff, 0xff, 0xff);
		$cl[2] = imagecolorallocate($output, 0xff, 0x00, 0x00);		

		for($y=0; $y < $height; $y++){
			for($x=0; $x < $width; $x++){
				$diff[0] = $this->colordiff(0x000000, $img_arr[$x][$y]);
				$diff[1] = $this->colordiff(0xffffff, $img_arr[$x][$y]);
				$diff[2] = $this->colordiff(0xff0000, $img_arr[$x][$y]);
				
				imagesetpixel($output, $x, $y, $cl[$this->chooseColor($diff)]);
				//imagesetpixel($output, $x, $y, $cl[$this->ditherColor($diff)]);
			}
		}
		// plop out a png of the dithered image.
		//Header("Content-type: image/png");
		//imagepng($output, NULL, 9); //to print to screen
		return $output;
	}	
	function dither_atkinson($img){
		//$img = imagecreatefromjpeg('./delayclose.jpg');
		imagefilter($img, IMG_FILTER_GRAYSCALE); 
		$width = imagesx($img);
		$height = imagesy($img);

		for($x=0; $x < $width; $x++){
			for($y=0; $y < $height; $y++){
				$img_arr[$x][$y] = imagecolorat($img, $x, $y);
			}
		}
		$output = imagecreate($width, $height);
		$black = imagecolorallocate($output, 0, 0, 0); //background color.
		$white = imagecolorallocate($output, 0xff, 0xff, 0xff);

		for($y=0; $y < $height; $y++){
			for($x=0; $x < $width; $x++){
				$old = $img_arr[$x][$y];
				if($old > 0xffffff*.5){ // This is the b/w threshold. Currently @ halfway between white and black.
					$new = 0xffffff;
					imagesetpixel($output, $x, $y, $white); // Only setting white pixels, because the image is already black.
				}else{
					$new = 0x000000;
				}
				$quant_error = $old-$new;
				$error_diffusion = (1/8)*$quant_error; //I can do this because this dither uses 1 value for the applied error diffusion.
				//dithering here.
				$img_arr[$x+1][$y] += $error_diffusion;
				$img_arr[$x+2][$y] += $error_diffusion;
				$img_arr[$x-1][$y+1] += $error_diffusion;
				$img_arr[$x][$y+1] += $error_diffusion;
				$img_arr[$x+1][$y+1] += $error_diffusion;
				$img_arr[$x][$y+2] += $error_diffusion;
			}
		}
		// plop out a png of the dithered image.
		//Header("Content-type: image/png");
		//imagepng($output, NULL, 9); //to print to screen
		return $output;
	}
}
?>