import config, image

int *def get_histogram(Image *image):
    int *histogram = ALLOCATE(256 * sizeof *histogram)
    for int i = 0; i < 256; i++:
        histogram[i] = 0
    for int j = 0; j < image->h; j++:
        B *pos = image->data.b + j * image->rowbytes
        for int i = 0; i < image->w; i++:
            int c = *(pos++)
            histogram[c]++
    return histogram

double *def get_probabilities(int *histogram):
    int n = 0
    for int i = 0; i < 256; i++:
        n += histogram[i]
    double *probabilities = ALLOCATE(256 * sizeof *probabilities)
    for int i = 0; i < 256; i++:
        probabilities[i] = (float)histogram[i] / n
    return probabilities

double def mean_p(double *probabilities):
    double mean = 0
    for int i = 0; i < 256; i++:
        mean += probabilities[i] * i
    return mean

int *def cumulate_histogram(int *histogram):
    int *cumulated = ALLOCATE(256 * sizeof *cumulated)
    cumulated[0] = histogram[0]
    for int i = 1; i < 256; i++:
        cumulated[i] = histogram[i] + cumulated[i - 1]
    return cumulated

def equalize(Image *image):
    int n = image->w * image->h
    int *histogram = get_histogram(image)
    int *cumulative = cumulate_histogram(histogram)

    for int j = 0; j < image->h; j++:
        B *pos = image->data.b + j * image->rowbytes
        for int i = 0; i < image->w; i++:
            int c = *pos
            int v = 255 * cumulative[c] / n
            *pos = v
            pos++

def adjust_luminance(Image *image, int black, white):
    """
    Adjust the luminance of the image in-place so that the result has at least
    black completely black and white completely white pixels (if possible).
    """
    int *histogram = get_histogram(image)
    int blackpoint, whitepoint
    int i

    if black:
        int bn = 0
        for i = 0; i < 256; i++:
            bn += histogram[i]
            if bn >= black:
                break
        blackpoint = i
    else:
        blackpoint = 0

    if white:
        int wn = 0
        for i = 255; i >= 0; i--:
            wn += histogram[i]
            if wn >= white:
                break
        whitepoint = i
    else:
        whitepoint = 255

    B *pos = image->data.b
    for i = 0; i < image->w * image->h; i++:
        int c = *pos
        int c_ = c - blackpoint
        c_ = c_ * 255 / (whitepoint - blackpoint)

        if c_ < 0: c_ = 0
        if c_ > 255: c_ = 255

        *pos = c_
        pos++
