Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0735149

Browse files
committed
Improve memory management and error handling in draw_gouraud_triangle(s) in the Agg backend.
svn path=/trunk/matplotlib/; revision=7628
1 parent 42886d7 commit 0735149

1 file changed

Lines changed: 52 additions & 44 deletions

File tree

src/_backend_agg.cpp

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,14 +1094,14 @@ RendererAgg::_draw_path_collection_generic
10941094
throw Py::ValueError("Offsets array must be Nx2");
10951095
}
10961096

1097-
PyArrayObject* facecolors = (PyArrayObject*)PyArray_FromObject
1097+
facecolors = (PyArrayObject*)PyArray_FromObject
10981098
(facecolors_obj.ptr(), PyArray_DOUBLE, 1, 2);
10991099
if (!facecolors ||
11001100
(PyArray_NDIM(facecolors) == 1 && PyArray_DIM(facecolors, 0) != 0) ||
11011101
(PyArray_NDIM(facecolors) == 2 && PyArray_DIM(facecolors, 1) != 4))
11021102
throw Py::ValueError("Facecolors must be a Nx4 numpy array or empty");
11031103

1104-
PyArrayObject* edgecolors = (PyArrayObject*)PyArray_FromObject
1104+
edgecolors = (PyArrayObject*)PyArray_FromObject
11051105
(edgecolors_obj.ptr(), PyArray_DOUBLE, 1, 2);
11061106
if (!edgecolors ||
11071107
(PyArray_NDIM(edgecolors) == 1 && PyArray_DIM(edgecolors, 0) != 0) ||
@@ -1459,13 +1459,14 @@ void
14591459
RendererAgg::_draw_gouraud_triangle(const GCAgg& gc,
14601460
const double* points, const double* colors, agg::trans_affine trans) {
14611461

1462-
typedef agg::rgba8 color_t;
1463-
typedef agg::span_gouraud_rgba<color_t> span_gen_t;
1464-
typedef agg::span_allocator<color_t> span_alloc_t;
1462+
typedef agg::rgba8 color_t;
1463+
typedef agg::span_gouraud_rgba<color_t> span_gen_t;
1464+
typedef agg::span_allocator<color_t> span_alloc_t;
14651465

14661466
theRasterizer.reset_clipping();
14671467
rendererBase.reset_clipping(true);
14681468
set_clipbox(gc.cliprect, theRasterizer);
1469+
/* TODO: Support clip paths */
14691470

14701471
trans *= agg::trans_affine_scaling(1.0, -1.0);
14711472
trans *= agg::trans_affine_translation(0.0, (double)height);
@@ -1492,45 +1493,49 @@ RendererAgg::_draw_gouraud_triangle(const GCAgg& gc,
14921493
0.5);
14931494

14941495
theRasterizer.add_path(span_gen);
1495-
agg::render_scanlines_aa(
1496-
theRasterizer, slineP8, rendererBase, span_alloc, span_gen);
1496+
1497+
agg::render_scanlines_aa(theRasterizer, slineP8, rendererBase, span_alloc, span_gen);
14971498
}
14981499

14991500
Py::Object
15001501
RendererAgg::draw_gouraud_triangle(const Py::Tuple& args) {
15011502
_VERBOSE("RendererAgg::draw_gouraud_triangle");
15021503
args.verify_length(4);
15031504

1504-
//segments, trans, clipbox, colors, linewidths, antialiaseds
15051505
GCAgg gc(args[0], dpi);
15061506
Py::Object points_obj = args[1];
15071507
Py::Object colors_obj = args[2];
15081508
agg::trans_affine trans = py_to_agg_transformation_matrix(args[3].ptr());
15091509

1510-
PyArrayObject* points = (PyArrayObject*)PyArray_ContiguousFromAny
1511-
(points_obj.ptr(), PyArray_DOUBLE, 2, 2);
1512-
if (!points ||
1513-
PyArray_DIM(points, 0) != 3 || PyArray_DIM(points, 1) != 2)
1514-
throw Py::ValueError("points must be a 3x2 numpy array");
1515-
1516-
PyArrayObject* colors = (PyArrayObject*)PyArray_ContiguousFromAny
1517-
(colors_obj.ptr(), PyArray_DOUBLE, 2, 2);
1518-
if (!colors ||
1519-
PyArray_DIM(colors, 0) != 3 || PyArray_DIM(colors, 1) != 4)
1520-
throw Py::ValueError("colors must be a 3x4 numpy array");
1510+
PyArrayObject* points = NULL;
1511+
PyArrayObject* colors = NULL;
15211512

15221513
try {
1514+
points = (PyArrayObject*)PyArray_ContiguousFromAny
1515+
(points_obj.ptr(), PyArray_DOUBLE, 2, 2);
1516+
if (!points ||
1517+
PyArray_DIM(points, 0) != 3 || PyArray_DIM(points, 1) != 2) {
1518+
throw Py::ValueError("points must be a 3x2 numpy array");
1519+
}
1520+
1521+
colors = (PyArrayObject*)PyArray_ContiguousFromAny
1522+
(colors_obj.ptr(), PyArray_DOUBLE, 2, 2);
1523+
if (!colors ||
1524+
PyArray_DIM(colors, 0) != 3 || PyArray_DIM(colors, 1) != 4) {
1525+
throw Py::ValueError("colors must be a 3x4 numpy array");
1526+
}
1527+
15231528
_draw_gouraud_triangle(
15241529
gc, (double*)PyArray_DATA(points), (double*)PyArray_DATA(colors), trans);
15251530
} catch (...) {
1526-
Py_DECREF(points);
1527-
Py_DECREF(colors);
1531+
Py_XDECREF(points);
1532+
Py_XDECREF(colors);
15281533

15291534
throw;
15301535
}
15311536

1532-
Py_DECREF(points);
1533-
Py_DECREF(colors);
1537+
Py_XDECREF(points);
1538+
Py_XDECREF(colors);
15341539

15351540
return Py::Object();
15361541
}
@@ -1544,42 +1549,45 @@ RendererAgg::draw_gouraud_triangles(const Py::Tuple& args) {
15441549
typedef agg::span_gouraud_rgba<color_t> span_gen_t;
15451550
typedef agg::span_allocator<color_t> span_alloc_t;
15461551

1547-
//segments, trans, clipbox, colors, linewidths, antialiaseds
15481552
GCAgg gc(args[0], dpi);
15491553
Py::Object points_obj = args[1];
15501554
Py::Object colors_obj = args[2];
15511555
agg::trans_affine trans = py_to_agg_transformation_matrix(args[3].ptr());
15521556

1553-
PyArrayObject* points = (PyArrayObject*)PyArray_ContiguousFromAny
1554-
(points_obj.ptr(), PyArray_DOUBLE, 3, 3);
1555-
if (!points ||
1556-
PyArray_DIM(points, 1) != 3 || PyArray_DIM(points, 2) != 2)
1557-
throw Py::ValueError("points must be a Nx3x2 numpy array");
1557+
PyArrayObject* points = NULL;
1558+
PyArrayObject* colors = NULL;
15581559

1559-
PyArrayObject* colors = (PyArrayObject*)PyArray_ContiguousFromAny
1560-
(colors_obj.ptr(), PyArray_DOUBLE, 3, 3);
1561-
if (!colors ||
1562-
PyArray_DIM(colors, 1) != 3 || PyArray_DIM(colors, 2) != 4)
1563-
throw Py::ValueError("colors must be a Nx3x4 numpy array");
1560+
try {
1561+
points = (PyArrayObject*)PyArray_ContiguousFromAny
1562+
(points_obj.ptr(), PyArray_DOUBLE, 3, 3);
1563+
if (!points ||
1564+
PyArray_DIM(points, 1) != 3 || PyArray_DIM(points, 2) != 2) {
1565+
throw Py::ValueError("points must be a Nx3x2 numpy array");
1566+
}
15641567

1565-
if (PyArray_DIM(points, 0) != PyArray_DIM(colors, 0)) {
1566-
throw Py::ValueError("points and colors arrays must be the same length");
1567-
}
1568+
colors = (PyArrayObject*)PyArray_ContiguousFromAny
1569+
(colors_obj.ptr(), PyArray_DOUBLE, 3, 3);
1570+
if (!colors ||
1571+
PyArray_DIM(colors, 1) != 3 || PyArray_DIM(colors, 2) != 4) {
1572+
throw Py::ValueError("colors must be a Nx3x4 numpy array");
1573+
}
1574+
1575+
if (PyArray_DIM(points, 0) != PyArray_DIM(colors, 0)) {
1576+
throw Py::ValueError("points and colors arrays must be the same length");
1577+
}
15681578

1569-
try {
15701579
for (int i = 0; i < PyArray_DIM(points, 0); ++i) {
1571-
_draw_gouraud_triangle(
1572-
gc, (double*)PyArray_GETPTR1(points, i), (double*)PyArray_GETPTR1(colors, i), trans);
1580+
_draw_gouraud_triangle(gc, (double*)PyArray_GETPTR1(points, i), (double*)PyArray_GETPTR1(colors, i), trans);
15731581
}
15741582
} catch (...) {
1575-
Py_DECREF(points);
1576-
Py_DECREF(colors);
1583+
Py_XDECREF(points);
1584+
Py_XDECREF(colors);
15771585

15781586
throw;
15791587
}
15801588

1581-
Py_DECREF(points);
1582-
Py_DECREF(colors);
1589+
Py_XDECREF(points);
1590+
Py_XDECREF(colors);
15831591

15841592
return Py::Object();
15851593
}

0 commit comments

Comments
 (0)