Skip to content

Agg: Remove 16-bit limits #28904

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/users/next_whats_new/increased_figure_limits.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Increased Figure limits with Agg renderer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Figures using the Agg renderer are now limited to 2**23 pixels in each
direction, instead of 2**16. Additionally, bugs that caused artists to not
render past 2**15 pixels horizontally have been fixed.

Note that if you are using a GUI backend, it may have its own smaller limits
(which may themselves depend on screen size.)
6 changes: 4 additions & 2 deletions extern/agg24-svn/include/agg_rasterizer_cells_aa.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,10 @@

if(dx >= dx_limit || dx <= -dx_limit)
{
int cx = (x1 + x2) >> 1;
int cy = (y1 + y2) >> 1;
// These are overflow safe versions of (x1 + x2) >> 1; divide each by 2
// first, then add 1 if both were odd.
int cx = (x1 >> 1) + (x2 >> 1) + ((x1 & 1) & (x2 & 1));
int cy = (y1 >> 1) + (y2 >> 1) + ((y1 & 1) & (y2 & 1));

Check warning on line 331 in extern/agg24-svn/include/agg_rasterizer_cells_aa.h

View check run for this annotation

Codecov / codecov/patch

extern/agg24-svn/include/agg_rasterizer_cells_aa.h#L330-L331

Added lines #L330 - L331 were not covered by tests
line(x1, y1, cx, cy);
line(cx, cy, x2, y2);
return;
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/tests/test_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def process_image(self, padded_src, dpi):


def test_too_large_image():
fig = plt.figure(figsize=(300, 1000))
fig = plt.figure(figsize=(300, 2**25))
buff = io.BytesIO()
with pytest.raises(ValueError):
fig.savefig(buff)
Expand Down
4 changes: 2 additions & 2 deletions src/_backend_agg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
throw std::range_error("dpi must be positive");
}

if (width >= 1 << 16 || height >= 1 << 16) {
if (width >= 1 << 23 || height >= 1 << 23) {
throw std::range_error(
"Image size of " + std::to_string(width) + "x" + std::to_string(height) +
" pixels is too large. It must be less than 2^16 in each direction.");
" pixels is too large. It must be less than 2^23 in each direction.");
}

unsigned stride(width * 4);
Expand Down
6 changes: 3 additions & 3 deletions src/_backend_agg.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ class RendererAgg
typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer;

typedef agg::scanline_p8 scanline_p8;
typedef agg::scanline_bin scanline_bin;
typedef agg::scanline32_p8 scanline_p8;
typedef agg::scanline32_bin scanline_bin;
typedef agg::amask_no_clip_gray8 alpha_mask_type;
typedef agg::scanline_u8_am<alpha_mask_type> scanline_am;
typedef agg::scanline32_u8_am<alpha_mask_type> scanline_am;

typedef agg::renderer_base<agg::pixfmt_gray8> renderer_base_alpha_mask_type;
typedef agg::renderer_scanline_aa_solid<renderer_base_alpha_mask_type> renderer_alpha_mask_type;
Expand Down
3 changes: 2 additions & 1 deletion src/_image_resample.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ void resample(

using renderer_t = agg::renderer_base<output_pixfmt_t>;
using rasterizer_t = agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl>;
using scanline_t = agg::scanline32_u8;

using reflect_t = agg::wrap_mode_reflect;
using image_accessor_t = agg::image_accessor_wrap<input_pixfmt_t, reflect_t, reflect_t>;
Expand Down Expand Up @@ -739,7 +740,7 @@ void resample(

span_alloc_t span_alloc;
rasterizer_t rasterizer;
agg::scanline_u8 scanline;
scanline_t scanline;

span_conv_alpha_t conv_alpha(params.alpha);

Expand Down
Loading