"""
piecewise affine equalization ipol demo web app
"""
from lib import base_app, build, http, image
from lib.misc import ctime
from lib.base_app import init_app
import shutil
import cherrypy
from cherrypy import TimeoutError
import os.path
import time
import PIL.Image
import PIL.ImageDraw
class app(base_app):
    """ piecewise affine equalization app """
    title = "Color and Contrast Enhancement by Controlled Piecewise Affine Histogram Equalization"
    xlink_article = 'http://www.ipol.im/pub/art/2012/lps-pae/'
    input_nb = 1
    input_max_pixels = 700 * 700 # max size (in pixels) of an input image
    input_max_weight = 10 * 1024 * 1024 # max size (in bytes) of an input file
    input_dtype = '3x8i' # input image expected data type
    input_ext = '.png' # input image expected extension (ie file format)
    is_test = False
    def __init__(self):
        """
        app setup
        """
        # setup the parent class
        base_dir = os.path.dirname(os.path.abspath(__file__))
        base_app.__init__(self, base_dir)
        # select the base_app steps to expose
        # index() and input_xxx() are generic
        base_app.index.im_func.exposed = True
        base_app.input_select.im_func.exposed = True
        base_app.input_upload.im_func.exposed = True
        # params() is modified from the template
        base_app.params.im_func.exposed = True
        # result() is modified from the template
        base_app.result.im_func.exposed = True
 
    def build(self):
        """ 
        program build/update
        """
        # store common file path in variables
        tgz_url = "http://www.ipol.im/pub/art/2012/lps-pae/piecewise_eq.tgz"
        tgz_file = self.dl_dir + "piecewise_eq.tgz"
        progs = ["piecewise_equalization"]
        src_bin = dict([(self.src_dir + 
                         os.path.join("piecewise_eq", prog),
                         self.bin_dir + prog)
                        for prog in progs])
        log_file = self.base_dir + "build.log"
        # get the latest source archive
        build.download(tgz_url, tgz_file)
        # test if any dest file is missing, or too old
        if all([(os.path.isfile(bin_file)
                 and ctime(tgz_file) < ctime(bin_file))
                for bin_file in src_bin.values()]):
            cherrypy.log("not rebuild needed",
                         context='BUILD', traceback=False)
        else:
            # extract the archive
            build.extract(tgz_file, self.src_dir)
            # build the programs
            build.run("make -j4 -C %s %s"
                      % (self.src_dir + "piecewise_eq", 
                      " ".join(progs)),
                      stdout=log_file)
            # save into bin dir
            if os.path.isdir(self.bin_dir):
                shutil.rmtree(self.bin_dir)
            os.mkdir(self.bin_dir)
            for (src, dst) in src_bin.items():
		#print "copy %s to %s" % (src, dst) 
                shutil.copy(src, dst)
            # cleanup the source dir
            shutil.rmtree(self.src_dir)
        return
    #
    # PARAMETER HANDLING
    #
    @cherrypy.expose
    @init_app
    def params(self, newrun=False, msg=None, s1="0", s2="3.0"):
        """
        configure the algo execution
        """
        if newrun:
            self.clone_input()
        return self.tmpl_out("params.html", msg=msg, s1=s1, s2=s2)
    @cherrypy.expose
    @init_app
    def wait(self, s1="0", s2="3.0"):
        """
        params handling and run redirection
        """
        # save the parameters
        try:
            self.cfg['param'] = {'s1' : float(s1), 
				 's2' : float(s2)}
            self.cfg.save()
        except ValueError:
            return self.error(errcode='badparams',
                              errmsg="The parameters must be numeric.")
        http.refresh(self.base_url + 'run?key=%s' % self.key)
        return self.tmpl_out("wait.html")
    @cherrypy.expose
    @init_app
    def run(self):
        """
        algorithm execution
        """
        # read the parameters
        s1 = self.cfg['param']['s1']
        s2 = self.cfg['param']['s2']
        # run the algorithm
        stdout = open(self.work_dir + 'stdout.txt', 'w')
        try:
            run_time = time.time()
            self.run_algo(s1, s2, stdout=stdout, timeout=self.timeout)
            self.cfg['info']['run_time'] = time.time() - run_time
            self.cfg.save()
        except TimeoutError:
            return self.error(errcode='timeout') 
        except RuntimeError:
            return self.error(errcode='runtime')
        http.redir_303(self.base_url + 'result?key=%s' % self.key)
        # archive
        if self.cfg['meta']['original']:
            ar = self.make_archive()
            ar.add_file("input_0.orig.png", info="uploaded image")
            ar.add_file("input_0.png", info="original image")
            ar.add_file("output_1_N2.png", info="result image 1 N=2 (RGB)")
            ar.add_file("output_2_N2.png", info="result image 2 N=2 (I)")
            ar.add_file("output_1_N3.png", info="result image 1 N=3 (RGB)")
            ar.add_file("output_2_N3.png", info="result image 2 N=3 (I)")
            ar.add_file("output_1_N4.png", info="result image 1 N=4 (RGB)")
            ar.add_file("output_2_N4.png", info="result image 2 N=4 (I)")
            ar.add_file("output_1_N5.png", info="result image 1 N=5 (RGB)")
            ar.add_file("output_2_N4.png", info="result image 2 N=5 (I)")
            ar.add_file("output_1_N10.png", info="result image 1 N=10 (RGB)")
            ar.add_file("output_2_N10.png", info="result image 2 N=10 (I)")
            ar.add_file("output_1_HE.png", info="result image 1 HE (RGB)")
            ar.add_file("output_2_HE.png", info="result image 2 HE (I)")
            ar.add_info({"smin": s1})
            ar.add_info({"smax": s2})
            ar.save()
        return self.tmpl_out("run.html")
    def drawtransformImages(self, imname0, imname1, channel, scale, fname=None):
        """
        Compute transform that converts values of image 0 to values of image 1, for the specified channel
        Images must be of the same size
        """
                
        #load images
        im0 = PIL.Image.open(imname0)
        im1 = PIL.Image.open(imname1)
    
        #check image size
        if im0.size != im1.size:
            raise ValueError("Images must be of the same size")
        
        # check image mode
        if im0.mode not in ("L", "RGB"):
            raise ValueError("Unsuported image mode for histogram equalization")
        if im1.mode not in ("L", "RGB"):
            raise ValueError("Unsuported image mode for histogram equalization")
        #load image values
        rgb2I = (0.333333, 0.333333, 0.333333, 0,
                 0, 0, 0, 0,
                 0, 0, 0, 0 )
        rgb2r = (1, 0, 0, 0,
                 0, 0, 0, 0,
                 0, 0, 0, 0 )
        rgb2g = (0, 1, 0, 0,
                 0, 0, 0, 0,
                 0, 0, 0, 0 )
        rgb2b = (0, 0, 1, 0,
                 0, 0, 0, 0,
                 0, 0, 0, 0 )
        if im0.mode == "RGB":
            if channel == "I":
                # compute gray level image: I = (R + G + B) / 3
                im0L = im0.convert("L", rgb2I)
            elif channel == "R":
                im0L = im0.convert("L", rgb2r)
            elif channel == "G":
                im0L = im0.convert("L", rgb2g)
            else:
                im0L = im0.convert("L", rgb2b)
            h0 = im0L.histogram()
        else: 
            #im0.mode == "L":
            h0 = im0.histogram()
        if im1.mode == "RGB":
            if channel == "I":
                # compute gray level image: I = (R + G + B) / 3


Answer:                 im1L = im1.convert("L", rgb2I)