Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 125 lines (103 sloc) 3.178 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
/* -*- mode: c++; c-basic-offset: 4 -*- */

#include <Python.h>

#define NO_IMPORT_ARRAY
#include "numpy/arrayobject.h"

#include "CXX/Objects.hxx"
#include "agg_trans_affine.h"

/** A helper function to convert from a Numpy affine transformation matrix
* to an agg::trans_affine. If errors = false then an Identity transform is returned.
*/
agg::trans_affine
py_to_agg_transformation_matrix(PyObject* obj, bool errors = true)
{
    PyArrayObject* matrix = NULL;

    /** If None either raise a TypeError or return an agg identity transform. */
    if (obj == Py_None)
    {
        if (errors)
        {
            throw Py::TypeError("Cannot convert None to an affine transform.");
        }

        return agg::trans_affine();
    }

    /** Try turning the object into an affine transform matrix. */
    try
    {
        matrix = (PyArrayObject*) PyArray_FromObject(obj, PyArray_DOUBLE, 2, 2);
        if (!matrix)
            throw std::exception();
    }
    catch (...)
    {
        Py_XDECREF(matrix);
        if (errors)
        {
            throw Py::TypeError("Unable to get an affine transform matrix from the given object.");
        }

        return agg::trans_affine();
    }

    /** Try turning the matrix into an agg transform. */
    try
    {
        if (PyArray_NDIM(matrix) == 2 || PyArray_DIM(matrix, 0) == 3 || PyArray_DIM(matrix, 1) == 3)
        {
            size_t stride0 = PyArray_STRIDE(matrix, 0);
            size_t stride1 = PyArray_STRIDE(matrix, 1);
            char* row0 = PyArray_BYTES(matrix);
            char* row1 = row0 + stride0;

            double a = *(double*)(row0);
            row0 += stride1;
            double c = *(double*)(row0);
            row0 += stride1;
            double e = *(double*)(row0);

            double b = *(double*)(row1);
            row1 += stride1;
            double d = *(double*)(row1);
            row1 += stride1;
            double f = *(double*)(row1);

            Py_XDECREF(matrix);

            return agg::trans_affine(a, b, c, d, e, f);
        }

        throw std::exception();
    }
    catch (...)
    {
        if (errors)
        {
            Py_XDECREF(matrix);
            throw Py::TypeError("Invalid affine transformation matrix.");
        }
    }

    Py_XDECREF(matrix);
    return agg::trans_affine();
}

bool
py_convert_bbox(PyObject* bbox_obj, double& l, double& b, double& r, double& t)
{
    PyArrayObject* bbox = NULL;

    if (bbox_obj == Py_None)
        return false;

    try
    {
        bbox = (PyArrayObject*) PyArray_FromObject(bbox_obj, PyArray_DOUBLE, 2, 2);

        if (!bbox || PyArray_NDIM(bbox) != 2 || PyArray_DIM(bbox, 0) != 2 || PyArray_DIM(bbox, 1) != 2)
        {
            throw Py::TypeError
            ("Expected a bbox array");
        }

        l = *(double*)PyArray_GETPTR2(bbox, 0, 0);
        b = *(double*)PyArray_GETPTR2(bbox, 0, 1);
        r = *(double*)PyArray_GETPTR2(bbox, 1, 0);
        t = *(double*)PyArray_GETPTR2(bbox, 1, 1);

        Py_XDECREF(bbox);
        bbox = NULL;
        return true;
    }
    catch (...)
    {
        Py_XDECREF(bbox);
        bbox = NULL;
        throw;
    }

    return false;
}
Something went wrong with that request. Please try again.