import numpy as np


def is_green(i, j):
    return (not i%2 and not j%2) or (i%2 and j%2)

def is_red(i, j):
    return not i%2 and j%2

def is_blue(i, j):
    return i%2 and not j%2


g_ker = np.array([
    [0, 0, -1, 0, 0],
    [0, 0, 2, 0, 0],
    [-1, 2, 4, 2, -1],
    [0, 0, 2, 0, 0],
    [0, 0, -1, 0, 0]
]) / 8

rgrrow_ker = np.array([
    [0, 0, 0.5, 0, 0],
    [0, -1, 0, -1, 0],
    [-1, 4, 5, 4, -1],
    [0, -1, 0, -1, 0],
    [0, 0, 0.5, 0, 0]
]) / 8

rgrcol_ker = np.array([
    [0, 0, -1, 0, 0],
    [0, -1, 4, -1, 0],
    [0.5, 0, 5, 0, 0.5],
    [0, -1, 4, -1, 0],
    [0, 0, -1, 0, 0]
]) / 8

rb_ker = np.array([
    [0, 0, -1.5, 0, 0],
    [0, 2, 0, 2, 0],
    [-1.5, 0, 6, 0, -1.5],
    [0, 2, 0, 2, 0],
    [0, 0, -1.5, 0, 0]
]) / 8



def high_quality_interpolation(image):

    res = np.empty((image.shape[0], image.shape[1], 3))
    
    estimated_green = np.zeros_like(image)
    estimated_red = np.zeros_like(image)
    estimated_blue = np.zeros_like(image)

    for i in range(2, image.shape[0]-2):
        for j in range(2, image.shape[1]-2):
            if (is_red(i, j)):
                estimated_red[i, j] = image[i, j]
                estimated_green[i, j] = (image[i-2:i+3, j-2:j+3] * g_ker).sum()
                estimated_blue[i, j] = (image[i-2:i+3, j-2:j+3] * rb_ker).sum()
            elif (is_blue(i, j)):
                estimated_red[i, j] = (image[i-2:i+3, j-2:j+3] * rb_ker).sum()
                estimated_green[i, j] = (image[i-2:i+3, j-2:j+3] * g_ker).sum()
                estimated_blue[i, j] = image[i, j]
            else:
                estimated_green[i, j] = image[i, j]
                if (is_red(i-1, j)):
                    estimated_red[i, j] = (image[i-2:i+3, j-2:j+3] * rgrcol_ker).sum()
                    estimated_blue[i, j] = (image[i-2:i+3, j-2:j+3] * rgrrow_ker).sum()
                else:
                    estimated_red[i, j] = (image[i-2:i+3, j-2:j+3] * rgrrow_ker).sum()
                    estimated_blue[i, j] = (image[i-2:i+3, j-2:j+3] * rgrcol_ker).sum()


    res[:, :, 0] = estimated_red.clip(0, 1)
    res[:, :, 1] = estimated_green.clip(0, 1)
    res[:, :, 2] = estimated_blue.clip(0, 1)
    
    return res