#!/usr/bin/python

# Show effects of good and bad gamma pixel merge.
# @author Thomas Troeger.

import Image

# the default gamma value to use.
default_gamma=2.2

# ----------------------- pixel conversion functions ------------------------

def toLinear(pixel, gamma=default_gamma):
	"""
	Calculate linear value for pixel value.
	"""
	return ((float(pixel)/255)**float(gamma))*255

def toPixel(linear, gamma=default_gamma):
	"""
	Calculate pixel value from linear value.
	"""
	return ((float(linear)/255)**(1.0/float(gamma)))*255

# -------------------------- pixel merge functions --------------------------

def merge_good(pixel1, pixel2, gamma=default_gamma):
	"""
	Merge two pixel values correctly.
	"""
	linear1=toLinear(pixel1, gamma)
	linear2=toLinear(pixel2, gamma)
	return toPixel((linear1+linear2)/2, gamma)

def merge_bad(pixel1, pixel2, gamma=default_gamma):
	"""
	Erroneously merge two pixel values.
	"""
	return (float(pixel1)+float(pixel2))/2

def merge_diff(pixel1, pixel2, gamma=default_gamma):
	"""
	Get absolute value of difference of good and bad pixel
	merge.
	"""
	linear_good=(toLinear(pixel1, gamma)+toLinear(pixel2, gamma))/2
	linear_bad=toLinear(int(round((float(pixel1)+float(pixel2))/2)), gamma)
	linear_diff=abs(linear_good-linear_bad)
	return toPixel(linear_diff, gamma)

# ---------------------------- output functions -----------------------------

def create_image(f):
	"""
	Create image from merge function.
	"""
	# create image file.
	img=Image.new("RGB", (256, 256))
	# set image pixels.
	for px in range(0, 256):
		for py in range(0, 256):
			pv=int(round(f(px, py)))
			img.putpixel((px, py), (pv, pv, pv))
	# save image.
	img.save("gamma_%s.png" % (f.__name__))


# ---------------------------------- main -----------------------------------

# create image with good pixel combination.
create_image(merge_good)
# create image with bad pixel combination.
create_image(merge_bad)
# create image with difference of good and bad combination.
create_image(merge_diff)