import imageio as iio
import matplotlib.pyplot as plt
import random as rd

## Exemples de palettes

palette_EGA = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.67], [0.0, 0.67, 0.0], [0.0, 0.67, 0.67], [0.67, 0.0, 0.0], [0.67, 0.0, 0.67], [0.67, 0.33, 0.0], [0.67, 0.67, 0.67], [0.33, 0.33, 0.33], [0.33, 0.33, 1.0], [0.33, 1.0, 0.33], [0.33, 1.0, 1.0], [1.0, 0.33, 0.33], [1.0, 0.33, 1.0], [1.0, 1.0, 0.33], [1.0, 1.0, 1.0]]

palette_LEGO = [[0.85, 0.85, 0.84], [0.62, 0.64, 0.64], [0.98, 0.85, 0.45], [0.9, 0.42, 0.33], [0.83, 0.74, 0.55], [0.64, 0.89, 0.72], [0.96, 0.55, 0.18], [0.93, 0.7, 0.8], [0.67, 0.79, 0.91], [0.84, 0.47, 0.0], [1.0, 0.51, 0.0], [0.93, 0.91, 0.1], [0.9, 0.62, 0.43], [0.86, 0.54, 0.02], [0.94, 0.2, 0.25], [0.89, 0.47, 0.8], [0.0, 0.24, 0.65], [1.0, 0.8, 0.0], [0.41, 0.25, 0.14], [0.15, 0.15, 0.12], [0.32, 0.33, 0.29], [0.0, 0.52, 0.24], [0.5, 0.88, 0.65], [1.0, 0.8, 0.55], [0.72, 0.38, 0.15], [0.8, 0.83, 0.92], [0.78, 0.85, 0.91], [1.0, 0.7, 0.67], [1.0, 0.53, 0.45], [0.42, 0.67, 0.89], [0.7, 0.71, 0.7], [0.61, 0.15, 0.71], [1.0, 0.64, 0.0], [1.0, 0.51, 0.0], [0.43, 0.3, 0.12], [0.12, 0.13, 0.67], [0.28, 0.36, 0.78], [0.81, 0.86, 0.0], [0.0, 0.7, 0.66], [0.61, 0.86, 0.85], [0.71, 0.74, 0.0], [0.76, 0.88, 0.54], [1.0, 0.71, 0.29], [1.0, 0.4, 0.12], [0.69, 0.09, 0.52], [1.0, 0.73, 0.56], [0.72, 0.38, 0.15], [1.0, 0.4, 0.12], [0.77, 0.91, 0.42], [0.36, 0.5, 0.58], [0.63, 0.57, 0.7], [1.0, 0.5, 0.2], [0.61, 0.58, 0.37], [0.17, 0.32, 0.2], [0.36, 0.47, 0.46], [0.47, 0.62, 0.56], [0.61, 0.38, 0.41], [0.61, 0.15, 0.26], [0.8, 0.54, 0.0], [1.0, 0.84, 0.0], [1.0, 0.64, 0.0], [0.48, 0.24, 0.23], [0.81, 0.27, 0.13], [0.64, 0.67, 0.68], [0.0, 0.28, 0.73], [0.0, 0.2, 0.63], [0.6, 0.11, 0.59], [0.36, 0.4, 0.44], [0.76, 0.78, 0.78], [0.67, 0.52, 0.0], [0.29, 0.47, 0.16], [0.17, 0.84, 0.77], [0.41, 0.7, 0.91], [0.19, 0.5, 0.89], [0.59, 0.22, 0.13], [0.38, 0.24, 0.13], [0.72, 0.52, 0.8], [0.41, 0.36, 0.78], [0.62, 0.68, 0.9], [0.91, 0.24, 0.67], [0.95, 0.65, 0.86], [0.99, 0.61, 0.7], [0.85, 0.78, 0.62], [0.99, 0.75, 0.53], [0.98, 0.86, 0.4], [0.02, 0.76, 0.87], [0.2, 0.0, 0.45], [0.26, 0.6, 0.71], [0.99, 0.78, 0.61], [0.19, 0.15, 0.11], [0.44, 0.77, 0.91], [0.73, 0.86, 0.82], [0.63, 0.37, 0.71], [0.79, 0.64, 0.87], [0.83, 0.92, 0.56], [0.45, 0.48, 0.3], [0.93, 0.85, 0.92]]

## Conversion RGB/CIELAB

def RGB_to_CIELAB(col):
    def g(s):
        return s/12.92 if s<0.0392 else ((s+0.055)/1.055)**2.4
    X, Y, Z = map(g, col)
    def f(v):
        return (903.3*v+16)/116 if v<8.85e-3 else v**(1/3)
    fx, fy, fz = map(f, (X/0.95, Y, Z/1.089))
    return [(116*fy-16)/100.0, (500*(fx-fy)+440)/880, (200*(fy-fz)+180)/360]

def CIELAB_to_RGB(lab):
    def f(v):
        return v**3 if v>0.207 else (116*v-16)/903.3
    L, a, b = lab
    L *= 100
    a = 880*a-440
    b = 360*b-180
    fy = (L+16)/116
    fx, fz = a/500+fy, fy-b/200
    X, Y, Z = f(fx)*0.95, f(fy), f(fz)*1.089
    def g(s):
        return 12.92*s if s<3.13e-3 else 1.055*s**(1/2.4)-0.055
    return [g(X), g(Y), g(Z)]

## Fonctions à écrire

def dist2(col1, col2):
    return 0.0 # à modifier

def plus_proche(col, pal):
    return 0 # à modifier

def applique_palette(img, pal):
    ... # à compléter

def palette_aleatoire(N):
    return [[]] # à modifier

def classe(img, pal):
    return [[]] # à modifier

def moyennes(img, idx, N):
    return [[]] # à modifier

def opt_palette(img, N, p):
    return [[]] # à modifier

def applique_palette_diff(img, pal):
    ... # à compléter

## Test des fonctions

img = [[list(pix) for pix in line] for line in
iio.imread("D:/tp5-dithering/kanagawa_wave_s.jpg")/255.0]

# Fonctions à appliquer à l'image
# par exemple :
# applique_palette(img, palette_EGA)

plt.imshow(img)
plt.show()