Esempio n. 1
0
static PyObject*
_curve_apply(PyObject *self, PyObject *args)
{
    char *image_mode;
    PyObject *buffer = NULL, *curve_a = NULL, *curve_r = NULL, *curve_g = NULL, *curve_b = NULL;

    if (!PyArg_ParseTuple(args, "sOOOOO:apply", &image_mode, &buffer, &curve_a, &curve_r, &curve_g, &curve_b)) {
        return NULL;
    }

    unsigned char *points_a = cubic_spline_interpolation(get_curve(curve_a), PyTuple_Size(curve_a), 256),
                  *points_r = cubic_spline_interpolation(get_curve(curve_r), PyTuple_Size(curve_r), 256),
                  *points_g = cubic_spline_interpolation(get_curve(curve_g), PyTuple_Size(curve_g), 256),
                  *points_b = cubic_spline_interpolation(get_curve(curve_b), PyTuple_Size(curve_b), 256);

    Py_ssize_t size = PyString_Size(buffer);
    unsigned char *ptr = (unsigned char *) PyString_AsString(buffer);
    int num_bytes = bytes_per_pixel(image_mode);

    int r_idx = rgb_order(image_mode, 'R'),
        g_idx = rgb_order(image_mode, 'G'),
        b_idx = rgb_order(image_mode, 'B'),
        i = 0, r, g, b;

    size -= num_bytes;

    for (; i <= size; i += num_bytes) {
        r = ptr[i + r_idx];
        g = ptr[i + g_idx];
        b = ptr[i + b_idx];

        r = points_r[r];
        g = points_g[g];
        b = points_b[b];

        r = points_a[r];
        g = points_a[g];
        b = points_a[b];

        ptr[i + r_idx] = ADJUST_COLOR(r);
        ptr[i + g_idx] = ADJUST_COLOR(g);
        ptr[i + b_idx] = ADJUST_COLOR(b);
    }

    free(points_a);
    free(points_r);
    free(points_g);
    free(points_b);

    Py_INCREF(buffer);
    return buffer;
}
Esempio n. 2
0
static PyObject*
_rgb_apply(PyObject *self, PyObject *args)
{
    PyObject *buffer = NULL, *image_mode = NULL, *delta_r = NULL, *delta_g = NULL, *delta_b = NULL;

    if (!PyArg_UnpackTuple(args, "apply", 5, 5, &image_mode, &delta_r, &delta_g, &delta_b, &buffer)) {
        return NULL;
    }

    char *image_mode_str = PyString_AsString(image_mode);
    Py_ssize_t size = PyString_Size(buffer);
    unsigned char *ptr = (unsigned char *) PyString_AsString(buffer);
    int delta_r_int = (int) PyInt_AsLong(delta_r),
        delta_g_int = (int) PyInt_AsLong(delta_g),
        delta_b_int = (int) PyInt_AsLong(delta_b);

    delta_r_int = (255 * delta_r_int) / 100;
    delta_g_int = (255 * delta_g_int) / 100;
    delta_b_int = (255 * delta_b_int) / 100;

    int r_idx = rgb_order(image_mode_str, 'R'),
        g_idx = rgb_order(image_mode_str, 'G'),
        b_idx = rgb_order(image_mode_str, 'B'),
        i = 0, r, g, b;

    size -= 3;
    for (; i <= size; i += 3) {
        r = ptr[i + r_idx];
        g = ptr[i + g_idx];
        b = ptr[i + b_idx];

        r += delta_r_int;
        g += delta_g_int;
        b += delta_b_int;

        ptr[i + r_idx] = ADJUST_COLOR(r);
        ptr[i + g_idx] = ADJUST_COLOR(g);
        ptr[i + b_idx] = ADJUST_COLOR(b);
    }

    Py_INCREF(buffer);
    return buffer;
}
Esempio n. 3
0
static PyObject*
_sharpen_apply(PyObject *self, PyObject *args)
{
    PyObject *buffer_py = NULL, *image_mode = NULL, *amount = NULL, *radius = NULL,
             *luminance_only = NULL, *width_py = NULL, *height_py = NULL;

    if (!PyArg_UnpackTuple(args, "apply", 7, 7, &image_mode, &width_py, &height_py, &amount, &radius, &luminance_only, &buffer_py)) {
        return NULL;
    }

    char *image_mode_str = PyString_AsString(image_mode);
    unsigned char *buffer = (unsigned char *) PyString_AsString(buffer_py);
    double amount_double = PyFloat_AsDouble(amount),
           radius_double = PyFloat_AsDouble(radius);

    char luminance_only_bool = (char) PyObject_IsTrue(luminance_only);

    int width = (int) PyInt_AsLong(width_py),
        height = (int) PyInt_AsLong(height_py);

    int num_bytes = bytes_per_pixel(image_mode_str);
    int r_idx = rgb_order(image_mode_str, 'R'),
        g_idx = rgb_order(image_mode_str, 'G'),
        b_idx = rgb_order(image_mode_str, 'B');

    sharpen_info info = {
      amount_double,
      radius_double,
      luminance_only_bool,
      width, height,
      buffer,
      {r_idx, g_idx, b_idx},
      num_bytes
    };

    run_sharpen(&info);

    Py_INCREF(buffer_py);
    return buffer_py;
}
Esempio n. 4
0
static PyObject*
_composite_apply(PyObject *self, PyObject *args)
{
    PyObject *py_image1 = NULL, *py_image2 = NULL, *image_mode = NULL,
             *w1, *h1, *w2, *h2, *py_x, *py_y, *py_merge = NULL;

    if (!PyArg_UnpackTuple(args, "apply", 9, 10, &image_mode, &py_image1, &w1, &h1, &py_image2, &w2, &h2, &py_x, &py_y, &py_merge)) {
        return NULL;
    }

    char *image_mode_str = PyString_AsString(image_mode);

    unsigned char *ptr1 = (unsigned char *) PyString_AsString(py_image1), *aux1 = NULL;
    unsigned char *ptr2 = (unsigned char *) PyString_AsString(py_image2), *aux2 = NULL;

    int width1 = (int) PyInt_AsLong(w1),
        width2 = (int) PyInt_AsLong(w2),
        height1 = (int) PyInt_AsLong(h1),
        height2 = (int) PyInt_AsLong(h2),
        x_pos = (int) PyInt_AsLong(py_x),
        y_pos = (int) PyInt_AsLong(py_y),
        merge = 1;

    if (py_merge) {
        merge = (int) PyInt_AsLong(py_merge);
    }

    int num_bytes = bytes_per_pixel(image_mode_str);
    int r_idx = rgb_order(image_mode_str, 'R'),
        g_idx = rgb_order(image_mode_str, 'G'),
        b_idx = rgb_order(image_mode_str, 'B'),
        a_idx = rgb_order(image_mode_str, 'A');


    int r1, g1, b1, a1, r2, g2, b2, a2, x, y, start_x = 0, start_y = 0;

    double delta, r, g, b, a;

    if (x_pos < 0) {
        start_x = -x_pos;
        x_pos = 0;
    }
    if (y_pos < 0) {
        start_y = -y_pos;
        y_pos = 0;
    }

    for (y = start_y; y < height2; ++y) {
        if (y_pos - start_y + y >= height1) {
            break;
        }
        int line_offset1 = ((y_pos + y - start_y) * width1 * num_bytes),
            line_offset2 = (y * width2 * num_bytes);

        aux1 = ptr1 + line_offset1 + (x_pos * num_bytes);
        aux2 = ptr2 + line_offset2 + (start_x * num_bytes);

        for (x = start_x; x < width2; ++x, aux1 += num_bytes, aux2 += num_bytes) {
            if (x_pos - start_x + x >= width1) {
                break;
            }

            r1 = aux1[r_idx];
            g1 = aux1[g_idx];
            b1 = aux1[b_idx];
            a1 = aux1[a_idx];

            r2 = aux2[r_idx];
            g2 = aux2[g_idx];
            b2 = aux2[b_idx];
            a2 = aux2[a_idx];

            a1 = 255 - a1;
            a2 = 255 - a2;

            if (merge) {
                delta = (a2 / MAX_RGB_DOUBLE) * (a1 / MAX_RGB_DOUBLE);

                a = MAX_RGB_DOUBLE * delta;

                delta = 1.0 - delta;
                delta = (delta <= SMALL_DOUBLE) ? 1.0 : (1.0 / delta);

                r = delta * ALPHA_COMPOSITE_COLOR_CHANNEL(r2, a2, r1, a1);
                g = delta * ALPHA_COMPOSITE_COLOR_CHANNEL(g2, a2, g1, a1);
                b = delta * ALPHA_COMPOSITE_COLOR_CHANNEL(b2, a2, b1, a1);
            } else {
                if (a1 == 0) {
                    r = r2;
                    g = g2;
                    b = b2;
                    a = a2;
                } else {
                    r = r1;
                    g = g1;
                    b = b1;
                    a = a1;
                }
            }

            a = 255.0 - a;

            aux1[r_idx] = ADJUST_COLOR_DOUBLE(r);
            aux1[g_idx] = ADJUST_COLOR_DOUBLE(g);
            aux1[b_idx] = ADJUST_COLOR_DOUBLE(b);
            aux1[a_idx] = ADJUST_COLOR_DOUBLE(a);
        }

    }

    Py_INCREF(py_image1);
    return py_image1;
}
Esempio n. 5
0
static PyObject*
_equalize_apply(PyObject *self, PyObject *args)
{
    PyObject *buffer = NULL, *image_mode = NULL;

    if (!PyArg_UnpackTuple(args, "apply", 2, 2, &image_mode, &buffer)) {
        return NULL;
    }

    char *image_mode_str = PyString_AsString(image_mode);
    Py_ssize_t original_size = PyString_Size(buffer);
    Py_ssize_t size = PyString_Size(buffer);
    unsigned char *ptr = (unsigned char *) PyString_AsString(buffer);

    int num_bytes = bytes_per_pixel(image_mode_str);
    int area = (int)(size / num_bytes);

    int r_idx = rgb_order(image_mode_str, 'R'),
        g_idx = rgb_order(image_mode_str, 'G'),
        b_idx = rgb_order(image_mode_str, 'B');

    int redHist[256] = {0};
    int redCumFreq[256] = {0};
    int greenHist[256] = {0};
    int greenCumFreq[256] = {0};
    int blueHist[256] = {0};
    int blueCumFreq[256] = {0};

    int i = 0, r, g, b;
    size -= num_bytes;
    for (; i <= size; i += num_bytes) {
        r = ptr[i + r_idx];
        g = ptr[i + g_idx];
        b = ptr[i + b_idx];

        redHist[r]++;
        greenHist[g]++;
        blueHist[b]++;
    }

    int rCum = 0, gCum = 0, bCum = 0;
    for(i = 0; i < 256; i++) {
        rCum += redHist[i];
        gCum += greenHist[i];
        bCum += blueHist[i];

        if (redHist[i] > 0) {
            redCumFreq[i] = rCum;
        }
        if (greenHist[i] > 0) {
            greenCumFreq[i] = gCum;
        }
        if (blueHist[i] > 0) {
            blueCumFreq[i] = bCum;
        }
    }

    int rMinCdf=0, gMinCdf=0, bMinCdf=0;
    i = 0;
    while (rMinCdf == 0 && gMinCdf == 0 && bMinCdf == 0 && i < 256) {
        if (rMinCdf == 0 && redCumFreq[i] != 0) {
            rMinCdf = redCumFreq[i];
        }
        if (gMinCdf == 0 && greenCumFreq[i] != 0) {
            gMinCdf = greenCumFreq[i];
        }
        if (bMinCdf == 0 && blueCumFreq[i] != 0) {
            bMinCdf = blueCumFreq[i];
        }
        i++;
    }

    size = original_size;
    size -= num_bytes;
    for (i = 0; i <= size; i += num_bytes) {
        r = ptr[i + r_idx];
        g = ptr[i + g_idx];
        b = ptr[i + b_idx];

        // Refer to http://en.wikipedia.org/wiki/Histogram_equalization
        float rColor = (((float)redCumFreq[r] - rMinCdf) / (area - rMinCdf)) * 255.0f;
        float gColor = (((float)greenCumFreq[g] - gMinCdf) / (area - gMinCdf)) * 255.0f;
        float bColor = (((float)blueCumFreq[b] - bMinCdf) / (area - bMinCdf)) * 255.0f;

        ptr[i + r_idx] = rColor;
        ptr[i + g_idx] = gColor;
        ptr[i + b_idx] = bColor;
    }

    Py_INCREF(buffer);
    return buffer;
}