From: <md...@us...> - 2010-06-28 13:54:59
|
Revision: 8474 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8474&view=rev Author: mdboom Date: 2010-06-28 13:54:52 +0000 (Mon, 28 Jun 2010) Log Message: ----------- Use automatic memory management to simplify the code. Modified Paths: -------------- trunk/matplotlib/src/_backend_agg.cpp trunk/matplotlib/src/_image.cpp trunk/matplotlib/src/agg_py_path_iterator.h Modified: trunk/matplotlib/src/_backend_agg.cpp =================================================================== --- trunk/matplotlib/src/_backend_agg.cpp 2010-06-28 13:51:16 UTC (rev 8473) +++ trunk/matplotlib/src/_backend_agg.cpp 2010-06-28 13:54:52 UTC (rev 8474) @@ -881,23 +881,24 @@ const unsigned char* buffer = NULL; int width, height; Py::Object image_obj = args[0]; - PyArrayObject* image_array = NULL; if (PyArray_Check(image_obj.ptr())) { - image_array = (PyArrayObject*)PyArray_FromObject(image_obj.ptr(), PyArray_UBYTE, 2, 2); + PyObject* image_array = PyArray_FromObject( + image_obj.ptr(), PyArray_UBYTE, 2, 2); if (!image_array) { throw Py::ValueError( "First argument to draw_text_image must be a FT2Font.Image object or a Nx2 uint8 numpy array."); } + image_obj = Py::Object(image_array, true); buffer = (unsigned char *)PyArray_DATA(image_array); width = PyArray_DIM(image_array, 1); height = PyArray_DIM(image_array, 0); } else { - FT2Image *image = static_cast<FT2Image*>(args[0].ptr()); + FT2Image *image = static_cast<FT2Image*>(image_obj.ptr()); if (!image->get_buffer()) { throw Py::ValueError( @@ -916,7 +917,6 @@ } catch (Py::TypeError) { - Py_XDECREF(image_array); throw Py::TypeError("Invalid input arguments to draw_text_image"); } @@ -959,8 +959,6 @@ theRasterizer.add_path(rect2); agg::render_scanlines(theRasterizer, slineP8, ri); - Py_XDECREF(image_array); - return Py::Object(); } @@ -1352,204 +1350,193 @@ typedef agg::conv_curve<snapped_t> snapped_curve_t; typedef agg::conv_curve<clipped_t> curve_t; - PyArrayObject* offsets = NULL; - PyArrayObject* facecolors = NULL; - PyArrayObject* edgecolors = NULL; + PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject + (offsets_obj.ptr(), PyArray_DOUBLE, 0, 2); + if (!offsets || + (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) || + (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) + { + Py_XDECREF(offsets); + throw Py::ValueError("Offsets array must be Nx2"); + } + Py::Object offsets_arr_obj((PyObject*)offsets, true); - try + PyArrayObject* facecolors = (PyArrayObject*)PyArray_FromObject + (facecolors_obj.ptr(), PyArray_DOUBLE, 1, 2); + if (!facecolors || + (PyArray_NDIM(facecolors) == 1 && PyArray_DIM(facecolors, 0) != 0) || + (PyArray_NDIM(facecolors) == 2 && PyArray_DIM(facecolors, 1) != 4)) { - offsets = (PyArrayObject*)PyArray_FromObject - (offsets_obj.ptr(), PyArray_DOUBLE, 0, 2); - if (!offsets || - (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) || - (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) - { - throw Py::ValueError("Offsets array must be Nx2"); - } + Py_XDECREF(facecolors); + throw Py::ValueError("Facecolors must be a Nx4 numpy array or empty"); + } + Py::Object facecolors_arr_obj((PyObject*)facecolors, true); - facecolors = (PyArrayObject*)PyArray_FromObject - (facecolors_obj.ptr(), PyArray_DOUBLE, 1, 2); - if (!facecolors || - (PyArray_NDIM(facecolors) == 1 && PyArray_DIM(facecolors, 0) != 0) || - (PyArray_NDIM(facecolors) == 2 && PyArray_DIM(facecolors, 1) != 4)) - { - throw Py::ValueError("Facecolors must be a Nx4 numpy array or empty"); - } + PyArrayObject* edgecolors = (PyArrayObject*)PyArray_FromObject + (edgecolors_obj.ptr(), PyArray_DOUBLE, 1, 2); + if (!edgecolors || + (PyArray_NDIM(edgecolors) == 1 && PyArray_DIM(edgecolors, 0) != 0) || + (PyArray_NDIM(edgecolors) == 2 && PyArray_DIM(edgecolors, 1) != 4)) + { + Py_XDECREF(edgecolors); + throw Py::ValueError("Edgecolors must be a Nx4 numpy array"); + } + Py::Object edgecolors_arr_obj((PyObject*)edgecolors, true); - edgecolors = (PyArrayObject*)PyArray_FromObject - (edgecolors_obj.ptr(), PyArray_DOUBLE, 1, 2); - if (!edgecolors || - (PyArray_NDIM(edgecolors) == 1 && PyArray_DIM(edgecolors, 0) != 0) || - (PyArray_NDIM(edgecolors) == 2 && PyArray_DIM(edgecolors, 1) != 4)) - { - throw Py::ValueError("Edgecolors must be a Nx4 numpy array"); - } + size_t Npaths = path_generator.num_paths(); + size_t Noffsets = offsets->dimensions[0]; + size_t N = std::max(Npaths, Noffsets); + size_t Ntransforms = std::min(transforms_obj.length(), N); + size_t Nfacecolors = facecolors->dimensions[0]; + size_t Nedgecolors = edgecolors->dimensions[0]; + size_t Nlinewidths = linewidths.length(); + size_t Nlinestyles = std::min(linestyles_obj.length(), N); + size_t Naa = antialiaseds.length(); - size_t Npaths = path_generator.num_paths(); - size_t Noffsets = offsets->dimensions[0]; - size_t N = std::max(Npaths, Noffsets); - size_t Ntransforms = std::min(transforms_obj.length(), N); - size_t Nfacecolors = facecolors->dimensions[0]; - size_t Nedgecolors = edgecolors->dimensions[0]; - size_t Nlinewidths = linewidths.length(); - size_t Nlinestyles = std::min(linestyles_obj.length(), N); - size_t Naa = antialiaseds.length(); + if ((Nfacecolors == 0 && Nedgecolors == 0) || Npaths == 0) + { + return Py::Object(); + } - if ((Nfacecolors == 0 && Nedgecolors == 0) || Npaths == 0) - { - return Py::Object(); - } + size_t i = 0; - size_t i = 0; + // Convert all of the transforms up front + typedef std::vector<agg::trans_affine> transforms_t; + transforms_t transforms; + transforms.reserve(Ntransforms); + for (i = 0; i < Ntransforms; ++i) + { + agg::trans_affine trans = py_to_agg_transformation_matrix + (transforms_obj[i].ptr(), false); + trans *= master_transform; - // Convert all of the transforms up front - typedef std::vector<agg::trans_affine> transforms_t; - transforms_t transforms; - transforms.reserve(Ntransforms); - for (i = 0; i < Ntransforms; ++i) - { - agg::trans_affine trans = py_to_agg_transformation_matrix - (transforms_obj[i].ptr(), false); - trans *= master_transform; + transforms.push_back(trans); + } - transforms.push_back(trans); + // Convert all the dashes up front + typedef std::vector<std::pair<double, GCAgg::dash_t> > dashes_t; + dashes_t dashes; + dashes.resize(Nlinestyles); + i = 0; + for (dashes_t::iterator d = dashes.begin(); + d != dashes.end(); ++d, ++i) + { + convert_dashes(Py::Tuple(linestyles_obj[i]), dpi, d->second, + d->first); + } + + // Handle any clipping globally + theRasterizer.reset_clipping(); + rendererBase.reset_clipping(true); + set_clipbox(cliprect, theRasterizer); + bool has_clippath = render_clippath(clippath, clippath_trans); + + // Set some defaults, assuming no face or edge + gc.linewidth = 0.0; + facepair_t face; + face.first = Nfacecolors != 0; + agg::trans_affine trans; + + for (i = 0; i < N; ++i) + { + typename PathGenerator::path_iterator path = path_generator(i); + + if (Ntransforms) + { + trans = transforms[i % Ntransforms]; } + else + { + trans = master_transform; + } - // Convert all the dashes up front - typedef std::vector<std::pair<double, GCAgg::dash_t> > dashes_t; - dashes_t dashes; - dashes.resize(Nlinestyles); - i = 0; - for (dashes_t::iterator d = dashes.begin(); - d != dashes.end(); ++d, ++i) + if (Noffsets) { - convert_dashes(Py::Tuple(linestyles_obj[i]), dpi, d->second, - d->first); + double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0); + double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1); + offset_trans.transform(&xo, &yo); + trans *= agg::trans_affine_translation(xo, yo); } - // Handle any clipping globally - theRasterizer.reset_clipping(); - rendererBase.reset_clipping(true); - set_clipbox(cliprect, theRasterizer); - bool has_clippath = render_clippath(clippath, clippath_trans); + // These transformations must be done post-offsets + trans *= agg::trans_affine_scaling(1.0, -1.0); + trans *= agg::trans_affine_translation(0.0, (double)height); - // Set some defaults, assuming no face or edge - gc.linewidth = 0.0; - facepair_t face; - face.first = Nfacecolors != 0; - agg::trans_affine trans; + if (Nfacecolors) + { + size_t fi = i % Nfacecolors; + face.second = agg::rgba( + *(double*)PyArray_GETPTR2(facecolors, fi, 0), + *(double*)PyArray_GETPTR2(facecolors, fi, 1), + *(double*)PyArray_GETPTR2(facecolors, fi, 2), + *(double*)PyArray_GETPTR2(facecolors, fi, 3)); + } - for (i = 0; i < N; ++i) + if (Nedgecolors) { - typename PathGenerator::path_iterator path = path_generator(i); + size_t ei = i % Nedgecolors; + gc.color = agg::rgba( + *(double*)PyArray_GETPTR2(edgecolors, ei, 0), + *(double*)PyArray_GETPTR2(edgecolors, ei, 1), + *(double*)PyArray_GETPTR2(edgecolors, ei, 2), + *(double*)PyArray_GETPTR2(edgecolors, ei, 3)); - if (Ntransforms) + if (Nlinewidths) { - trans = transforms[i % Ntransforms]; + gc.linewidth = double(Py::Float(linewidths[i % Nlinewidths])) * dpi / 72.0; } else { - trans = master_transform; + gc.linewidth = 1.0; } - - if (Noffsets) + if (Nlinestyles) { - double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0); - double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1); - offset_trans.transform(&xo, &yo); - trans *= agg::trans_affine_translation(xo, yo); + gc.dashes = dashes[i % Nlinestyles].second; + gc.dashOffset = dashes[i % Nlinestyles].first; } + } - // These transformations must be done post-offsets - trans *= agg::trans_affine_scaling(1.0, -1.0); - trans *= agg::trans_affine_translation(0.0, (double)height); + bool do_clip = !face.first && gc.hatchpath.isNone() && !has_curves; - if (Nfacecolors) + if (check_snap) + { + gc.isaa = bool(Py::Int(antialiaseds[i % Naa])); + + transformed_path_t tpath(path, trans); + nan_removed_t nan_removed(tpath, true, has_curves); + clipped_t clipped(nan_removed, do_clip, width, height); + snapped_t snapped(clipped, gc.snap_mode, + path.total_vertices(), gc.linewidth); + if (has_curves) { - size_t fi = i % Nfacecolors; - face.second = agg::rgba( - *(double*)PyArray_GETPTR2(facecolors, fi, 0), - *(double*)PyArray_GETPTR2(facecolors, fi, 1), - *(double*)PyArray_GETPTR2(facecolors, fi, 2), - *(double*)PyArray_GETPTR2(facecolors, fi, 3)); + snapped_curve_t curve(snapped); + _draw_path(curve, has_clippath, face, gc); } - - if (Nedgecolors) + else { - size_t ei = i % Nedgecolors; - gc.color = agg::rgba( - *(double*)PyArray_GETPTR2(edgecolors, ei, 0), - *(double*)PyArray_GETPTR2(edgecolors, ei, 1), - *(double*)PyArray_GETPTR2(edgecolors, ei, 2), - *(double*)PyArray_GETPTR2(edgecolors, ei, 3)); - - if (Nlinewidths) - { - gc.linewidth = double(Py::Float(linewidths[i % Nlinewidths])) * dpi / 72.0; - } - else - { - gc.linewidth = 1.0; - } - if (Nlinestyles) - { - gc.dashes = dashes[i % Nlinestyles].second; - gc.dashOffset = dashes[i % Nlinestyles].first; - } + _draw_path(snapped, has_clippath, face, gc); } + } + else + { + gc.isaa = bool(Py::Int(antialiaseds[i % Naa])); - bool do_clip = !face.first && gc.hatchpath.isNone() && !has_curves; - - if (check_snap) + transformed_path_t tpath(path, trans); + nan_removed_t nan_removed(tpath, true, has_curves); + clipped_t clipped(nan_removed, do_clip, width, height); + if (has_curves) { - gc.isaa = bool(Py::Int(antialiaseds[i % Naa])); - - transformed_path_t tpath(path, trans); - nan_removed_t nan_removed(tpath, true, has_curves); - clipped_t clipped(nan_removed, do_clip, width, height); - snapped_t snapped(clipped, gc.snap_mode, - path.total_vertices(), gc.linewidth); - if (has_curves) - { - snapped_curve_t curve(snapped); - _draw_path(curve, has_clippath, face, gc); - } - else - { - _draw_path(snapped, has_clippath, face, gc); - } + curve_t curve(clipped); + _draw_path(curve, has_clippath, face, gc); } else { - gc.isaa = bool(Py::Int(antialiaseds[i % Naa])); - - transformed_path_t tpath(path, trans); - nan_removed_t nan_removed(tpath, true, has_curves); - clipped_t clipped(nan_removed, do_clip, width, height); - if (has_curves) - { - curve_t curve(clipped); - _draw_path(curve, has_clippath, face, gc); - } - else - { - _draw_path(clipped, has_clippath, face, gc); - } + _draw_path(clipped, has_clippath, face, gc); } } - - Py_XDECREF(offsets); - Py_XDECREF(facecolors); - Py_XDECREF(edgecolors); - return Py::Object(); } - catch (...) - { - Py_XDECREF(offsets); - Py_XDECREF(facecolors); - Py_XDECREF(edgecolors); - throw; - } + + return Py::Object(); } @@ -1741,7 +1728,7 @@ agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[1].ptr()); size_t mesh_width = Py::Int(args[2]); size_t mesh_height = Py::Int(args[3]); - PyObject* coordinates = args[4].ptr(); + Py::Object coordinates = args[4]; Py::Object offsets_obj = args[5]; agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[6].ptr()); Py::Object facecolors_obj = args[7]; @@ -1749,7 +1736,7 @@ bool showedges = (bool)Py::Int(args[9]); bool free_edgecolors = false; - QuadMeshGenerator path_generator(mesh_width, mesh_height, coordinates); + QuadMeshGenerator path_generator(mesh_width, mesh_height, coordinates.ptr()); Py::SeqBase<Py::Object> transforms_obj; Py::Object edgecolors_obj; @@ -1763,9 +1750,8 @@ { npy_intp dims[] = { 1, 4, 0 }; double data[] = { 0, 0, 0, 1 }; - edgecolors_obj = PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE, - (char*)data); - free_edgecolors = true; + edgecolors_obj = Py::Object(PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE, + (char*)data), true); } else { @@ -1783,9 +1769,7 @@ try { - try - { - _draw_path_collection_generic<QuadMeshGenerator, 0, 0> + _draw_path_collection_generic<QuadMeshGenerator, 0, 0> (gc, master_transform, gc.cliprect, @@ -1800,26 +1784,12 @@ linewidths, linestyles_obj, antialiaseds); - } - catch (const char* e) - { - throw Py::RuntimeError(e); - } } - catch (...) + catch (const char* e) { - if (free_edgecolors) - { - Py_XDECREF(edgecolors_obj.ptr()); - } - throw; + throw Py::RuntimeError(e); } - if (free_edgecolors) - { - Py_XDECREF(edgecolors_obj.ptr()); - } - return Py::Object(); } @@ -1890,46 +1860,34 @@ Py::Object colors_obj = args[2]; agg::trans_affine trans = py_to_agg_transformation_matrix(args[3].ptr()); - PyArrayObject* points = NULL; - PyArrayObject* colors = NULL; - theRasterizer.reset_clipping(); rendererBase.reset_clipping(true); set_clipbox(gc.cliprect, theRasterizer); bool has_clippath = render_clippath(gc.clippath, gc.clippath_trans); - try + PyArrayObject* points = (PyArrayObject*)PyArray_ContiguousFromAny + (points_obj.ptr(), PyArray_DOUBLE, 2, 2); + if (!points || + PyArray_DIM(points, 0) != 3 || PyArray_DIM(points, 1) != 2) { - points = (PyArrayObject*)PyArray_ContiguousFromAny - (points_obj.ptr(), PyArray_DOUBLE, 2, 2); - if (!points || - PyArray_DIM(points, 0) != 3 || PyArray_DIM(points, 1) != 2) - { - throw Py::ValueError("points must be a 3x2 numpy array"); - } - - colors = (PyArrayObject*)PyArray_ContiguousFromAny - (colors_obj.ptr(), PyArray_DOUBLE, 2, 2); - if (!colors || - PyArray_DIM(colors, 0) != 3 || PyArray_DIM(colors, 1) != 4) - { - throw Py::ValueError("colors must be a 3x4 numpy array"); - } - - _draw_gouraud_triangle( - (double*)PyArray_DATA(points), (double*)PyArray_DATA(colors), - trans, has_clippath); + Py_XDECREF(points); + throw Py::ValueError("points must be a 3x2 numpy array"); } - catch (...) + points_obj = Py::Object((PyObject*)points, true); + + PyArrayObject* colors = (PyArrayObject*)PyArray_ContiguousFromAny + (colors_obj.ptr(), PyArray_DOUBLE, 2, 2); + if (!colors || + PyArray_DIM(colors, 0) != 3 || PyArray_DIM(colors, 1) != 4) { - Py_XDECREF(points); Py_XDECREF(colors); - - throw; + throw Py::ValueError("colors must be a 3x4 numpy array"); } + colors_obj = Py::Object((PyObject*)colors, true); - Py_XDECREF(points); - Py_XDECREF(colors); + _draw_gouraud_triangle( + (double*)PyArray_DATA(points), (double*)PyArray_DATA(colors), + trans, has_clippath); return Py::Object(); } @@ -1950,54 +1908,42 @@ Py::Object colors_obj = args[2]; agg::trans_affine trans = py_to_agg_transformation_matrix(args[3].ptr()); - PyArrayObject* points = NULL; - PyArrayObject* colors = NULL; - theRasterizer.reset_clipping(); rendererBase.reset_clipping(true); set_clipbox(gc.cliprect, theRasterizer); bool has_clippath = render_clippath(gc.clippath, gc.clippath_trans); - try + PyArrayObject* points = (PyArrayObject*)PyArray_ContiguousFromAny + (points_obj.ptr(), PyArray_DOUBLE, 3, 3); + if (!points || + PyArray_DIM(points, 1) != 3 || PyArray_DIM(points, 2) != 2) { - points = (PyArrayObject*)PyArray_ContiguousFromAny - (points_obj.ptr(), PyArray_DOUBLE, 3, 3); - if (!points || - PyArray_DIM(points, 1) != 3 || PyArray_DIM(points, 2) != 2) - { - throw Py::ValueError("points must be a Nx3x2 numpy array"); - } - - colors = (PyArrayObject*)PyArray_ContiguousFromAny - (colors_obj.ptr(), PyArray_DOUBLE, 3, 3); - if (!colors || - PyArray_DIM(colors, 1) != 3 || PyArray_DIM(colors, 2) != 4) - { - throw Py::ValueError("colors must be a Nx3x4 numpy array"); - } - - if (PyArray_DIM(points, 0) != PyArray_DIM(colors, 0)) - { - throw Py::ValueError("points and colors arrays must be the same length"); - } - - for (int i = 0; i < PyArray_DIM(points, 0); ++i) - { - _draw_gouraud_triangle( - (double*)PyArray_GETPTR1(points, i), - (double*)PyArray_GETPTR1(colors, i), trans, has_clippath); - } + Py_XDECREF(points); + throw Py::ValueError("points must be a Nx3x2 numpy array"); } - catch (...) + points_obj = Py::Object((PyObject*)points, true); + + PyArrayObject* colors = (PyArrayObject*)PyArray_ContiguousFromAny + (colors_obj.ptr(), PyArray_DOUBLE, 3, 3); + if (!colors || + PyArray_DIM(colors, 1) != 3 || PyArray_DIM(colors, 2) != 4) { - Py_XDECREF(points); Py_XDECREF(colors); + throw Py::ValueError("colors must be a Nx3x4 numpy array"); + } + colors_obj = Py::Object((PyObject*)colors, true); - throw; + if (PyArray_DIM(points, 0) != PyArray_DIM(colors, 0)) + { + throw Py::ValueError("points and colors arrays must be the same length"); } - Py_XDECREF(points); - Py_XDECREF(colors); + for (int i = 0; i < PyArray_DIM(points, 0); ++i) + { + _draw_gouraud_triangle( + (double*)PyArray_GETPTR1(points, i), + (double*)PyArray_GETPTR1(colors, i), trans, has_clippath); + } return Py::Object(); } Modified: trunk/matplotlib/src/_image.cpp =================================================================== --- trunk/matplotlib/src/_image.cpp 2010-06-28 13:51:16 UTC (rev 8473) +++ trunk/matplotlib/src/_image.cpp 2010-06-28 13:54:52 UTC (rev 8474) @@ -864,15 +864,13 @@ Py::Object x = args[0]; int isoutput = Py::Int(args[1]); - //PyArrayObject *A = (PyArrayObject *) PyArray_ContiguousFromObject(x.ptr(), PyArray_DOUBLE, 2, 3); PyArrayObject *A = (PyArrayObject *) PyArray_FromObject(x.ptr(), PyArray_DOUBLE, 2, 3); - if (A == NULL) { throw Py::ValueError("Array must be rank 2 or 3 of doubles"); } + Py::Object A_obj((PyObject *)A, true); - Image* imo = new Image; imo->rowsIn = A->dimensions[0]; @@ -924,7 +922,6 @@ if (A->dimensions[2] != 3 && A->dimensions[2] != 4) { - Py_XDECREF(A); throw Py::ValueError(Printf("3rd dimension must be length 3 (RGB) or 4 (RGBA); found %d", A->dimensions[2]).str()); } @@ -959,11 +956,9 @@ } else // error { - Py_XDECREF(A); throw Py::ValueError("Illegal array rank; must be rank; must 2 or 3"); } buffer -= NUMBYTES; - Py_XDECREF(A); return Py::asObject(imo); } @@ -986,12 +981,11 @@ Py::Object x = args[0]; int isoutput = Py::Int(args[1]); PyArrayObject *A = (PyArrayObject *) PyArray_ContiguousFromObject(x.ptr(), PyArray_DOUBLE, 2, 3); - //PyArrayObject *A = (PyArrayObject *) PyArray_FromObject(x.ptr(), PyArray_DOUBLE, 2, 3); - if (A == NULL) { throw Py::ValueError("Array must be rank 2 or 3 of doubles"); } + Py::Object A_obj((PyObject*)A, true); Image* imo = new Image; @@ -1043,7 +1037,6 @@ { if (A->dimensions[2] != 3 && A->dimensions[2] != 4) { - Py_XDECREF(A); throw Py::ValueError(Printf("3rd dimension must be length 3 (RGB) or 4 (RGBA); found %d", A->dimensions[2]).str()); } @@ -1072,11 +1065,9 @@ } else // error { - Py_XDECREF(A); throw Py::ValueError("Illegal array rank; must be rank; must 2 or 3"); } buffer -= NUMBYTES; - Py_XDECREF(A); return Py::asObject(imo); } @@ -1104,6 +1095,8 @@ { throw Py::ValueError("Array must have 3 dimensions"); } + Py::Object A_obj((PyObject*)A, true); + if (A->dimensions[2] < 3 || A->dimensions[2] > 4) { throw Py::ValueError("Array dimension 3 must have size 3 or 4"); @@ -1146,7 +1139,6 @@ buffer -= N; arrbuf -= imo->rowsIn * imo->colsIn; } - Py_XDECREF(A); if (isoutput) { @@ -1456,18 +1448,9 @@ unsigned int * rowstarts , unsigned int*colstarts , float *acols , float *arows) { - if (x) - { - Py_XDECREF(x); - } - if (y) - { - Py_XDECREF(y); - } - if (d) - { - Py_XDECREF(d); - } + Py_XDECREF(x); + Py_XDECREF(y); + Py_XDECREF(d); if (rowstarts) { PyMem_Free(rowstarts); @@ -1494,7 +1477,9 @@ if (args.length() != 7) + { throw Py::TypeError("Incorrect number of arguments (7 expected)"); + } Py::Object xp = args[0]; Py::Object yp = args[1]; @@ -1510,7 +1495,10 @@ } if (bounds.length() != 4) + { throw Py::TypeError("Incorrect number of bounds (4 expected)"); + } + float x_min = Py::Float(bounds[0]); float x_max = Py::Float(bounds[1]); float y_min = Py::Float(bounds[2]); @@ -1529,8 +1517,8 @@ PyArrayObject *x = NULL; PyArrayObject *y = NULL; PyArrayObject *d = NULL; - unsigned int * rowstarts = NULL; - unsigned int*colstarts = NULL; + unsigned int *rowstarts = NULL; + unsigned int *colstarts = NULL; float *acols = NULL; float *arows = NULL; @@ -1704,7 +1692,24 @@ } +void _pcolor2_cleanup(PyArrayObject* x, PyArrayObject* y, PyArrayObject *d, + PyArrayObject* bg, int *irows, int*jcols) +{ + Py_XDECREF(x); + Py_XDECREF(y); + Py_XDECREF(d); + Py_XDECREF(bg); + if (irows) + { + PyMem_Free(irows); + } + if (jcols) + { + PyMem_Free(jcols); + } +} + char __image_module_pcolor2__doc__[] = "pcolor2(x, y, data, rows, cols, bounds, bg)\n" "\n" @@ -1748,33 +1753,39 @@ // Check we have something to output to if (rows == 0 || cols == 0) + { throw Py::ValueError("rows or cols is zero; there are no pixels"); + } + PyArrayObject* x = NULL; + PyArrayObject* y = NULL; + PyArrayObject* d = NULL; + PyArrayObject* bg = NULL; + int* irows = NULL; + int* jcols = NULL; + // Get numpy arrays - PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xp.ptr(), - PyArray_DOUBLE, 1, 1); + x = (PyArrayObject *) PyArray_ContiguousFromObject(xp.ptr(), PyArray_DOUBLE, 1, 1); if (x == NULL) + { + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::ValueError("x is of incorrect type (wanted 1D double)"); - PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yp.ptr(), - PyArray_DOUBLE, 1, 1); + } + y = (PyArrayObject *) PyArray_ContiguousFromObject(yp.ptr(), PyArray_DOUBLE, 1, 1); if (y == NULL) { - Py_XDECREF(x); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::ValueError("y is of incorrect type (wanted 1D double)"); } - PyArrayObject *d = (PyArrayObject *) PyArray_ContiguousFromObject(dp.ptr(), - PyArray_UBYTE, 3, 3); + d = (PyArrayObject *) PyArray_ContiguousFromObject(dp.ptr(), PyArray_UBYTE, 3, 3); if (d == NULL) { - Py_XDECREF(x); - Py_XDECREF(y); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::ValueError("data is of incorrect type (wanted 3D uint8)"); } if (d->dimensions[2] != 4) { - Py_XDECREF(x); - Py_XDECREF(y); - Py_XDECREF(d); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::ValueError("data must be in RGBA format"); } @@ -1783,49 +1794,33 @@ int ny = y->dimensions[0]; if (nx != d->dimensions[1] + 1 || ny != d->dimensions[0] + 1) { - Py_XDECREF(x); - Py_XDECREF(y); - Py_XDECREF(d); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::ValueError("data and axis bin boundary dimensions are incompatible"); } - PyArrayObject *bg = (PyArrayObject *) PyArray_ContiguousFromObject(bgp.ptr(), - PyArray_UBYTE, 1, 1); + bg = (PyArrayObject *) PyArray_ContiguousFromObject(bgp.ptr(), PyArray_UBYTE, 1, 1); if (bg == NULL) { - Py_XDECREF(x); - Py_XDECREF(y); - Py_XDECREF(d); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::ValueError("bg is of incorrect type (wanted 1D uint8)"); } if (bg->dimensions[0] != 4) { - Py_XDECREF(x); - Py_XDECREF(y); - Py_XDECREF(d); - Py_XDECREF(bg); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::ValueError("bg must be in RGBA format"); } - // Allocate memory for pointer arrays - int * irows = reinterpret_cast<int*>(PyMem_Malloc(sizeof(int) * rows)); + irows = reinterpret_cast<int*>(PyMem_Malloc(sizeof(int) * rows)); if (irows == NULL) { - Py_XDECREF(x); - Py_XDECREF(y); - Py_XDECREF(d); - Py_XDECREF(bg); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::MemoryError("Cannot allocate memory for lookup table"); } - int * jcols = reinterpret_cast<int*>(PyMem_Malloc(sizeof(int) * cols)); + jcols = reinterpret_cast<int*>(PyMem_Malloc(sizeof(int) * cols)); if (jcols == NULL) { - Py_XDECREF(x); - Py_XDECREF(y); - Py_XDECREF(d); - Py_XDECREF(bg); - PyMem_Free(irows); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::MemoryError("Cannot allocate memory for lookup table"); } @@ -1839,12 +1834,7 @@ agg::int8u *buffer = new agg::int8u[NUMBYTES]; if (buffer == NULL) { - Py_XDECREF(x); - Py_XDECREF(y); - Py_XDECREF(d); - Py_XDECREF(bg); - PyMem_Free(irows); - PyMem_Free(jcols); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); throw Py::MemoryError("Could not allocate memory for image"); } @@ -1886,12 +1876,7 @@ imo->bufferOut = buffer; imo->rbufOut->attach(imo->bufferOut, imo->colsOut, imo->rowsOut, imo->colsOut * imo->BPP); - Py_XDECREF(x); - Py_XDECREF(y); - Py_XDECREF(d); - Py_XDECREF(bg); - PyMem_Free(irows); - PyMem_Free(jcols); + _pcolor2_cleanup(x, y, d, bg, irows, jcols); return Py::asObject(imo); } Modified: trunk/matplotlib/src/agg_py_path_iterator.h =================================================================== --- trunk/matplotlib/src/agg_py_path_iterator.h 2010-06-28 13:51:16 UTC (rev 8473) +++ trunk/matplotlib/src/agg_py_path_iterator.h 2010-06-28 13:54:52 UTC (rev 8474) @@ -24,8 +24,8 @@ underlying data arrays, so that Python reference counting can work. */ - PyArrayObject* m_vertices; - PyArrayObject* m_codes; + Py::Object m_vertices; + Py::Object m_codes; size_t m_iterator; size_t m_total_vertices; @@ -39,7 +39,7 @@ public: /* path_obj is an instance of the class Path as defined in path.py */ inline PathIterator(const Py::Object& path_obj) : - m_vertices(NULL), m_codes(NULL), m_iterator(0), m_should_simplify(false), + m_vertices(), m_codes(), m_iterator(0), m_should_simplify(false), m_simplify_threshold(1.0 / 9.0) { Py::Object vertices_obj = path_obj.getAttr("vertices"); @@ -47,45 +47,42 @@ Py::Object should_simplify_obj = path_obj.getAttr("should_simplify"); Py::Object simplify_threshold_obj = path_obj.getAttr("simplify_threshold"); - m_vertices = (PyArrayObject*)PyArray_FromObject - (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2); - if (!m_vertices || - PyArray_DIM(m_vertices, 1) != 2) + PyObject* vertices_arr = PyArray_FromObject(vertices_obj.ptr(), PyArray_DOUBLE, 2, 2); + if (!vertices_arr) { - Py_XDECREF(m_vertices); - m_vertices = NULL; throw Py::ValueError("Invalid vertices array."); } + m_vertices = Py::Object(vertices_arr, true); + if (PyArray_DIM(m_vertices.ptr(), 1) != 2) + { + throw Py::ValueError("Invalid vertices array."); + } + if (codes_obj.ptr() != Py_None) { - m_codes = (PyArrayObject*)PyArray_FromObject - (codes_obj.ptr(), PyArray_UINT8, 1, 1); - if (!m_codes) + PyObject* codes_arr = PyArray_FromObject(codes_obj.ptr(), PyArray_UINT8, 1, 1); + + if (!codes_arr) { - Py_XDECREF(m_vertices); - m_vertices = NULL; throw Py::ValueError("Invalid codes array."); } - if (PyArray_DIM(m_codes, 0) != PyArray_DIM(m_vertices, 0)) + + m_codes = Py::Object(codes_arr, true); + if (PyArray_DIM(m_codes.ptr(), 0) != PyArray_DIM(m_vertices.ptr(), 0)) { - Py_XDECREF(m_vertices); - m_vertices = NULL; - Py_XDECREF(m_codes); - m_codes = NULL; throw Py::ValueError("Codes array is wrong length"); } } m_should_simplify = should_simplify_obj.isTrue(); - m_total_vertices = PyArray_DIM(m_vertices, 0); + m_total_vertices = PyArray_DIM(m_vertices.ptr(), 0); m_simplify_threshold = Py::Float(simplify_threshold_obj); } ~PathIterator() { - Py_XDECREF(m_vertices); - Py_XDECREF(m_codes); + } inline unsigned vertex(double* x, double* y) @@ -94,13 +91,13 @@ const size_t idx = m_iterator++; - char* pair = (char*)PyArray_GETPTR2(m_vertices, idx, 0); + char* pair = (char*)PyArray_GETPTR2(m_vertices.ptr(), idx, 0); *x = *(double*)pair; - *y = *(double*)(pair + PyArray_STRIDE(m_vertices, 1)); + *y = *(double*)(pair + PyArray_STRIDE(m_vertices.ptr(), 1)); - if (m_codes) + if (!m_codes.isNone()) { - return (unsigned)(*(char *)PyArray_GETPTR1(m_codes, idx)); + return (unsigned)(*(char *)PyArray_GETPTR1(m_codes.ptr(), idx)); } else { @@ -130,7 +127,7 @@ inline bool has_curves() { - return m_codes != NULL; + return !m_codes.isNone(); } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |