8000 Implement a better way to handle overflow in the Agg backend. · matplotlib/matplotlib@4301543 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4301543

Browse files
committed
Implement a better way to handle overflow in the Agg backend.
1 parent b81c917 commit 4301543

File tree

2 files changed

+70
-18
lines changed

2 files changed

+70
-18
lines changed

agg24/include/agg_rasterizer_cells_aa.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@
2929
#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED
3030
#define AGG_RASTERIZER_CELLS_AA_INCLUDED
3131

32-
#include "CXX/Exception.hxx"
33-
#include <exception>
32+
#include <stdexcept>
3433
#include <string.h>
3534
#include <math.h>
3635
#include "agg_math.h"
@@ -183,9 +182,9 @@ namespace agg
183182
{
184183
if((m_num_cells & cell_block_mask) == 0)
185184
{
186-
if(m_num_blocks >= cell_block_limit) {
187-
throw Py::OverflowError(
188-
"Agg rendering complexity exceeded. Consider downsampling or decimating your data.");
185+
if (m_num_blocks >= cell_block_limit)
186+
{
187+
throw std::overflow_error("Allocated too many blocks");
189188
}
190189
allocate_block();
191190
}

src/_backend_agg.cpp

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,11 @@ RendererAgg::render_clippath(const Py::Object& clippath,
619619
rendererBaseAlphaMask.clear(agg::gray8(0, 0));
620620
transformed_path_t transformed_clippath(clippath_iter, trans);
621621
agg::conv_curve<transformed_path_t> curved_clippath(transformed_clippath);
622-
theRasterizer.add_path(curved_clippath);
622+
try {
623+
theRasterizer.add_path(curved_clippath);
624+
} catch (std::overflow_error &e) {
625+
throw Py::OverflowError(e.what());
626+
}
623627
rendererAlphaMask.color(agg::gray8(255, 255));
624628
agg::render_scanlines(theRasterizer, scanlineAlphaMask, rendererAlphaMask);
625629
lastclippath = clippath;
@@ -698,7 +702,11 @@ RendererAgg::draw_markers(const Py::Tuple& args)
698702
unsigned fillSize = 0;
699703
if (face.first)
700704
{
701-
theRasterizer.add_path(marker_path_curve);
705+
try {
706+
theRasterizer.add_path(marker_path_curve);
707+
} catch (std::overflow_error &e) {
708+
throw Py::OverflowError(e.what());
709+
}
702710
agg::render_scanlines(theRasterizer, slineP8, scanlines);
703711
fillSize = scanlines.byte_size();
704712
if (fillSize >= MARKER_CACHE_SIZE)
@@ -713,7 +721,11 @@ RendererAgg::draw_markers(const Py::Tuple& args)
713721
stroke.line_cap(gc.cap);
714722
stroke.line_join(gc.join);
715723
theRasterizer.reset();
716-
theRasterizer.add_path(stroke);
724+
try {
725+
theRasterizer.add_path(stroke);
726+
} catch (std::overflow_error &e) {
727+
throw Py::OverflowError(e.what());
728+
}
717729
agg::render_scanlines(theRasterizer, slineP8, scanlines);
718730
unsigned strokeSize = scanlines.byte_size();
719731
if (strokeSize >= MARKER_CACHE_SIZE)
@@ -980,7 +992,11 @@ RendererAgg::draw_text_image(const Py::Tuple& args)
980992
span_gen_type output_span_generator(&image_span_generator, gc.color);
981993
renderer_type ri(rendererBase, sa, output_span_generator);
982994

983-
theRasterizer.add_path(rect2);
995+
try {
996+
theRasterizer.add_path(rect2);
997+
} catch (std::overflow_error &e) {
998+
throw Py::OverflowError(e.what());
999+
}
9841000
agg::render_scanlines(theRasterizer, slineP8, ri);
9851001

9861002
return Py::Object();
@@ -1117,7 +1133,11 @@ RendererAgg::draw_image(const Py::Tuple& args)
11171133
amask_ren_type r(pfa);
11181134
renderer_type_alpha ri(r, sa, spans);
11191135

1120-
theRasterizer.add_path(rect2);
1136+
try {
1137+
theRasterizer.add_path(rect2);
1138+
} catch (std::overflow_error &e) {
1139+
throw Py::OverflowError(e.what());
1140+
}
11211141
agg::render_scanlines(theRasterizer, slineP8, ri);
11221142
}
11231143
else
@@ -1131,7 +1151,11 @@ RendererAgg::draw_image(const Py::Tuple& args)
11311151
ren_type r(pixFmt);
11321152
renderer_type ri(r, sa, spans);
11331153

1134-
theRasterizer.add_path(rect2);
1154+
try {
1155+
theRasterizer.add_path(rect2);
1156+
} catch (std::overflow_error &e) {
1157+
throw Py::OverflowError(e.what());
1158+
}
11351159
agg::render_scanlines(theRasterizer, slineP8, ri);
11361160
}
11371161

@@ -1166,7 +1190,11 @@ void RendererAgg::_draw_path(path_t& path, bool has_clippath,
11661190
// Render face
11671191
if (face.first)
11681192
{
1169-
theRasterizer.add_path(path);
1193+
try {
1194+
theRasterizer.add_path(path);
1195+
} catch (std::overflow_error &e) {
1196+
throw Py::OverflowError(e.what());
1197+
}
11701198

11711199
if (gc.isaa)
11721200
{
@@ -1233,9 +1261,17 @@ void RendererAgg::_draw_path(path_t& path, bool has_clippath,
12331261
rb.clear(agg::rgba(0.0, 0.0, 0.0, 0.0));
12341262
rs.color(gc.color);
12351263

1236-
theRasterizer.add_path(hatch_path_curve);
1264+
try {
1265+
theRasterizer.add_path(hatch_path_curve);
1266+
} catch (std::overflow_error &e) {
1267+
throw Py::OverflowError(e.what());
1268+
}
12371269
agg::render_scanlines(theRasterizer, slineP8, rs);
1238-
theRasterizer.add_path(hatch_path_stroke);
1270+
try {
1271+
theRasterizer.add_path(hatch_path_stroke);
1272+
} catch (std::overflow_error &e) {
1273+
throw Py::OverflowError(e.what());
1274+
}
12391275
agg::render_scanlines(theRasterizer, slineP8, rs);
12401276

12411277
// Put clipping back on, if originally set on entry to this
@@ -1252,7 +1288,11 @@ void RendererAgg::_draw_path(path_t& path, bool has_clippath,
12521288
agg::span_allocator<agg::rgba8> sa;
12531289
img_source_type img_src(hatch_img_pixf);
12541290
span_gen_type sg(img_src, 0, 0);
1255-
theRasterizer.add_path(path);
1291+
try {
1292+
theRasterizer.add_path(path);
1293+
} catch (std::overflow_error &e) {
1294+
throw Py::OverflowError(e.what());
1295+
}
12561296
agg::render_scanlines_aa(theRasterizer, slineP8, rendererBase, sa, sg);
12571297
}
12581298

@@ -1270,7 +1310,11 @@ void RendererAgg::_draw_path(path_t& path, bool has_clippath,
12701310
stroke.width(linewidth);
12711311
stroke.line_cap(gc.cap);
12721312
stroke.line_join(gc.join);
1273-
theRasterizer.add_path(stroke);
1313+
try {
1314+
theRasterizer.add_path(stroke);
1315+
} catch (std::overflow_error &e) {
1316+
throw Py::OverflowError(e.what());
1317+
}
12741318
}
12751319
else
12761320
{
@@ -1291,7 +1335,11 @@ void RendererAgg::_draw_path(path_t& path, bool has_clippath,
12911335
stroke.line_cap(gc.cap);
12921336
stroke.line_join(gc.join);
12931337
stroke.width(linewidth);
1294-
theRasterizer.add_path(stroke);
1338+
try {
1339+
theRasterizer.add_path(stroke);
1340+
} catch (std::overflow_error &e) {
1341+
throw Py::OverflowError(e.what());
1342+
}
12951343
}
12961344

12971345
if (gc.isaa)
@@ -1888,7 +1936,12 @@ RendererAgg::_draw_gouraud_triangle(const double* points,
18881936
tpoints[4], tpoints[5],
18891937
0.5);
18901938

1891-
theRasterizer.add_path(span_gen);
1939+
try {
1940+
theRasterizer.add_path(span_gen);
1941+
} catch (std::overflow_error &e) {
1942+
throw Py::OverflowError(e.what()
1943+
);
1944+
}
18921945

18931946
if (has_clippath)
18941947
{

0 commit comments

Comments
 (0)
0