<commit_before># -*- python -*-

"""Colour Mixer

NumPy does not do overflow checking when adding or multiplying
integers, so currently the only way to clip results efficiently
(without making copies of the data) is with an extension such as this
one.

"""

import numpy as np
cimport numpy as np

import cython

cdef extern from "math.h":
    float exp(float)
    float pow(float, float)


@cython.boundscheck(False)
def add(np.ndarray[np.uint8_t, ndim=3] img,
        np.ndarray[np.uint8_t, ndim=3] stateimg,
        int channel, int amount):
    """Add a given amount to a colour channel of `stateimg`, and
    store the result in `img`.  Overflow is clipped.

    Parameters
    ----------
    img : (M, N, 3) ndarray of uint8
        Output image.
    stateimg : (M, N, 3) ndarray of uint8
        Input image.
    channel : int
        Channel (0 for "red", 1 for "green", 2 for "blue").
    amount : int
        Value to add.

    """
    cdef int height = img.shape[0]
    cdef int width = img.shape[1]
    cdef int k = channel
    cdef int n = amount

    cdef np.int16_t op_result

    cdef int i, j
    for i in range(height):
        for j in range(width):
            op_result = <np.int16_t>(stateimg[i,j,k] + n)
            if op_result > 255:
                img[i, j, k] = 255
            elif op_result < 0:
                img[i, j, k] = 0
            else:
                img[i, j, k] = <np.uint8_t>op_result


@cython.boundscheck(False)
def multiply(np.ndarray[np.uint8_t, ndim=3] img,
             np.ndarray[np.uint8_t, ndim=3] stateimg,
             int channel, float amount):
    """Multiply a colour channel of `stateimg` by a certain amount, and
    store the result in `img`.  Overflow is clipped.

    Parameters
    ----------
    img : (M, N, 3) ndarray of uint8
        Output image.
    stateimg : (M, N, 3) ndarray of uint8
        Input image.
    channel : int
        Channel (0 for "red", 1 for "green", 2 for "blue").
    amount : float
        Multiplication factor.

    """
    cdef int height = img.shape[0]
    cdef int width = img.shape[1]
    cdef int k = channel
    cdef float n = amount

    cdef float op_result

    cdef int i, j
    for i in range(height):
        for j in range(width):
            op_result = <float>(stateimg[i,j,k] * n)
            if op_result > 255:
                img[i, j, k] = 255
            elif op_result < 0:
                img[i, j, k] = 0
            else:
                img[i, j, k] = <np.uint8_t>op_result


@cython.boundscheck(False)
def brightness(np.ndarray[np.uint8_t, ndim=3] img,
             np.ndarray[np.uint8_t, ndim=3] stateimg,
             float factor, int offset):
    """Modify the brightness of an image.
    'factor' is multiplied to all channels, which are
    then added by 'amount'. Overflow is clipped.

    Parameters
    ----------
    img : (M, N, 3) ndarray of uint8
        Output image.
    stateimg : (M, N, 3) ndarray of uint8
        Input image.
    factor : float
        Multiplication factor.
    offset : int
        Ammount to add to each channel.

    """

    cdef int height = img.shape[0]
    cdef int width = img.shape[1]

    cdef float op_result

    cdef int i, j, k
    for i in range(height):
        for j in range(width):
            for k in range(3):
                op_result = <float>((stateimg[i,j,k] * factor + offset))

                if op_result > 255:
                    img[i, j, k] = 255
                elif op_result < 0:
                    img[i, j, k] = 0
                else:
                    img[i, j, k] = <np.uint8_t>op_result


@cython.boundscheck(False)
def sigmoid_gamma(np.ndarray[np.uint8_t, ndim=3] img,
                  np.ndarray[np.uint8_t, ndim=3] stateimg,
                  float alpha, float beta):

    cdef int height = img.shape[0]
    cdef int width = img.shape[1]

    cdef float c1, c2, r, g, b

    cdef int i, j, k
    for i in range(height):
        for j in range(width):
            r = <float>stateimg[i,j,0] / 255.
            g = <float>stateimg[i,j,1] / 255.
            b = <float>stateimg[i,j,2] / 255.

            c1 = 1 / (1 + exp(beta))
            c2 = 1 / (1 + exp(beta - alpha)) - c1

            r = 1 / (1 + exp(beta - r * alpha))
            r = (r - c1) / c2

            g = 1 / (1 + exp(beta - g * alpha))
            g = (g - c1) / c2

            b = 1 / (1 + exp(beta - b * alpha))
            b = (b - c1) / c2

            img[i,j,0] = <np.uint8_t>(r * 255)
            img[i,j,1] = <np.uint8_t>(g * 255)
            img[i,j,2] = <np.uint8_t>(b * 255)


@cython.boundscheck(False)
def gamma(np.ndarray[np.uint8_t, ndim=3] img,
          np.ndarray[np.uint8_t, ndim=3] stateimg,
          float gamma):

    cdef int height = img.shape[0]
    cdef int width = img.shape[1]

    cdef float r, g, b

    cdef int i, j
    for i in range(height):
        for j in range(width):
            r = <float>stateimg[i,j,0] / 255.
            g = <float>stateimg[i,j,1] / 255.
            b = <float>stateimg[i,j,2] / 255.

            img[i,j,0] = <np.uint8_t>(pow(r, gamma) * 255)
            img[i,j,1] = <np.uint8_t>(pow(g, gamma) * 255)
            img[i,j,2] = <np.uint8_t>(pow(b, gamma) * 255)



cdef void rgb_2_hsv(float* RGB, float* HSV):
    cdef float R, G, B, H, S, V, MAX, MIN
    R = RGB[0]
    G = RGB[1]
    B = RGB[2]

    if R > 255:
        R = 255
    elif R < 0:
        R = 0
    else:
        pass
<commit_msg>fixed the gamma correction in the color mixer.<commit_after># -*- python -*-

"""Colour Mixer

NumPy does not do overflow checking when adding or multiplying
integers, so currently the only way to clip results efficiently
(without making copies of the data) is with an extension such as this
one.

"""

import numpy as np
cimport numpy as np

import cython

cdef extern from "math.h":
    float exp(float)
    float pow(float, float)


@cython.boundscheck(False)
def add(np.ndarray[np.uint8_t, ndim=3] img,
        np.ndarray[np.uint8_t, ndim=3] stateimg,
        int channel, int amount):
    """Add a given amount to a colour channel of `stateimg`, and
    store the result in `img`.  Overflow is clipped.

    Parameters
    ----------
    img : (M, N, 3) ndarray of uint8
        Output image.
    stateimg : (M, N, 3) ndarray of uint8
        Input image.
    channel : int
        Channel (0 for "red", 1 for "green", 2 for "blue").
    amount : int
        Value to add.

    """
    cdef int height = img.shape[0]
    cdef int width = img.shape[1]
    cdef int k = channel
    cdef int n = amount

    cdef np.int16_t op_result

    cdef int i, j
    for i in range(height):
        for j in range(width):
            op_result = <np.int16_t>(stateimg[i,j,k] + n)
            if op_result > 255:
                img[i, j, k] = 255
            elif op_result < 0:
                img[i, j, k] = 0
            else:
                img[i, j, k] = <np.uint8_t>op_result


@cython.boundscheck(False)
def multiply(np.ndarray[np.uint8_t, ndim=3] img,
             np.ndarray[np.uint8_t, ndim=3] stateimg,
             int channel, float amount):
    """Multiply a colour channel of `stateimg` by a certain amount, and
    store the result in `img`.  Overflow is clipped.

    Parameters
    ----------
    img : (M, N, 3) ndarray of uint8
        Output image.
    stateimg : (M, N, 3) ndarray of uint8
        Input image.
    channel : int
        Channel (0 for "red", 1 for "green", 2 for "blue").
    amount : float
        Multiplication factor.

    """
    cdef int height = img.shape[0]
    cdef int width = img.shape[1]
    cdef int k = channel
    cdef float n = amount

    cdef float op_result

    cdef int i, j
    for i in range(height):
        for j in range(width):
            op_result = <float>(stateimg[i,j,k] * n)
            if op_result > 255:
                img[i, j, k] = 255
            elif op_result < 0:
                img[i, j, k] = 0
            else:
                img[i, j, k] = <np.uint8_t>op_result


@cython.boundscheck(False)
def brightness(np.ndarray[np.uint8_t, ndim=3] img,
             np.ndarray[np.uint8_t, ndim=3] stateimg,
             float factor, int offset):
    """Modify the brightness of an image.
    'factor' is multiplied to all channels, which are
    then added by 'amount'. Overflow is clipped.

    Parameters
    ----------
    img : (M, N, 3) ndarray of uint8
        Output image.
    stateimg : (M, N, 3) ndarray of uint8
        Input image.
    factor : float
        Multiplication factor.
    offset : int
        Ammount to add to each channel.

    """

    cdef int height = img.shape[0]
    cdef int width = img.shape[1]

    cdef float op_result

    cdef int i, j, k
    for i in range(height):
        for j in range(width):
            for k in range(3):
                op_result = <float>((stateimg[i,j,k] * factor + offset))

                if op_result > 255:
                    img[i, j, k] = 255
                elif op_result < 0:
                    img[i, j, k] = 0
                else:
                    img[i, j, k] = <np.uint8_t>op_result


@cython.boundscheck(False)
def sigmoid_gamma(np.ndarray[np.uint8_t, ndim=3] img,
                  np.ndarray[np.uint8_t, ndim=3] stateimg,
                  float alpha, float beta):

    cdef int height = img.shape[0]
    cdef int width = img.shape[1]

    cdef float c1, c2, r, g, b

    cdef int i, j, k
    for i in range(height):
        for j in range(width):
            r = <float>stateimg[i,j,0] / 255.
            g = <float>stateimg[i,j,1] / 255.
            b = <float>stateimg[i,j,2] / 255.

            c1 = 1 / (1 + exp(beta))
            c2 = 1 / (1 + exp(beta - alpha)) - c1

            r = 1 / (1 + exp(beta - r * alpha))
            r = (r - c1) / c2

            g = 1 / (1 + exp(beta - g * alpha))
            g = (g - c1) / c2

            b = 1 / (1 + exp(beta - b * alpha))
            b = (b - c1) / c2

            img[i,j,0] = <np.uint8_t>(r * 255)
            img[i,j,1] = <np.uint8_t>(g * 255)
            img[i,j,2] = <np.uint8_t>(b * 255)


@cython.boundscheck(False)
def gamma(np.ndarray[np.uint8_t, ndim=3] img,
          np.ndarray[np.uint8_t, ndim=3] stateimg,
          float gamma):

    cdef int height = img.shape[0]
    cdef int width = img.shape[1]

    cdef float r, g, b

    cdef int i, j

    gamma = 1./gamma
    for i in range(height):
        for j in range(width):
            r = <float>stateimg[i,j,0] / 255.
            g = <float>stateimg[i,j,1] / 255.
            b = <float>stateimg[i,j,2] / 255.

            img[i,j,0] = <np.uint8_t>(pow(r, gamma) * 255)
            img[i,j,1] = <np.uint8_t>(pow(g, gamma) * 255)
            img[i,j,2] = <np.uint8_t>(pow(b, gamma) * 255)



cdef void rgb_2_hsv(float* RGB, float* HSV):
    cdef float R, G, B, H, S, V, MAX, MIN
    R = RGB[0]
    G = RGB[1]
    B = RGB[2]

    if R > 255:
        R = 255
    elif R < 0:
        R = 0
    else:
        pass

{'fraction_non_alphanumeric': 0.1258344764517604, 'fraction_numerical': 0.03063557384545039, 'mean_word_length': 1.7049220875587434, 'pattern_counts': {'":': 2, '<': 47, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5551550', 'n_tokens_mistral': 4144, 'n_tokens_neox': 3842, 'n_words': 1207}