Dot tends to build long rectangular graphs, where one dimension can exceed the 16-bit limit, while the other fits in a common desktop display. This means the abort in the file gvrender_gd.c is premature.
Attached is a patch. It attempts to support 31-bit dimensions for PNGs,
where the total size fits in 32-bits. There are multiple code paths
for PNGs due to the plethora of graphviz optional plugins.
This patches the GD and Cairo code paths.
Input file: b1818.dot
Comments: [erg] Same as bug 1818.
Fix:
diff -Naur graphviz-2.24.0/plugin/gd/gvrender_gd.c NEW-graphviz-2.24.0/plugin/gd/gvrender_gd.c
--- graphviz-2.24.0/plugin/gd/gvrender_gd.c 2009-06-02 21:10:56.000000000 -0400
+++ NEW-graphviz-2.24.0/plugin/gd/gvrender_gd.c 2009-11-15 17:52:07.000000000 -0500
@@ -46,6 +46,12 @@
extern boolean mapbool(char *);
extern pointf Bezier(pointf * V, int degree, double t, pointf * Left, pointf * Right);
+/* return maximum dimensions supported by the given format. */ +static unsigned int format_max_xy (format_type t) +{ + return (t == FORMAT_PNG || t == FORMAT_GD || t==FORMAT_GD2) ? INT_MAX : 32767 ; +} + #define BEZIERSUBDIVISION 10
static void gdgen_resolve_color(GVJ_t * job, gvcolor_t * color) @@ -72,9 +78,6 @@
static int white, black, transparent, basecolor;
-#define GD_XMAX 32767 -#define GD_YMAX 32767 - static void gdgen_begin_page(GVJ_t * job) { char *bgcolor_str = NULL, *truecolor_str = NULL; @@ -102,9 +105,14 @@ fprintf(stderr, "%s: using existing GD imagen", job->common->cmdname); im = (gdImagePtr) (job->context); } else { - if (job->width >= GD_XMAX || job->height >= GD_YMAX) { - double scale = MIN((double)GD_XMAX / job->width, - (double)GD_YMAX / job->height); + fprintf(stderr,"gdgen_begin_page. GD_XYMAX=%u w=%u h=%un", GD_XYMAX, job->width, job->height); + if (job->width >= GD_XYMAX || job->height >= GD_XYMAX + || job->width >= INT_MAX - job->height ){ + double scale = MIN( + MIN((double)GD_XYMAX / job->width, + (double)GD_XYMAX / job->height), + INT_MAX/ ((double)job->width + job->height) + ); job->width *= scale; job->height *= scale; job->zoom *= scale; diff -Naur graphviz-2.24.0/plugin/pango/gvrender_pango.c NEW-graphviz-2.24.0/plugin/pango/gvrender_pango.c --- graphviz-2.24.0/plugin/pango/gvrender_pango.c 2009-06-02 21:10:57.000000000 -0400 +++ NEW-graphviz-2.24.0/plugin/pango/gvrender_pango.c 2009-11-15 17:36:22.000000000 -0500 @@ -77,8 +77,7 @@ return CAIRO_STATUS_WRITE_ERROR; }
-#define CAIRO_XMAX 32767 -#define CAIRO_YMAX 32767 +#define CAIRO_XYMAX INT_MAX
static void cairogen_begin_page(GVJ_t * job)
{
@@ -109,9 +108,11 @@
case FORMAT_CAIRO:
case FORMAT_PNG:
default:
- if (job->width >= CAIRO_XMAX || job->height >= CAIRO_YMAX) {
- double scale = MIN((double)CAIRO_XMAX / job->width,
- (double)CAIRO_YMAX / job->height);
+ if (job->width >= CAIRO_XYMAX || job->height >= CAIRO_XYMAX
+ || job->width >= INT_MAX - job->height ){
+ double scale = MIN( MIN((double)CAIRO_XYMAX / job->width,
+ (double)CAIRO_XYMAX / job->height),
+ INT_MAX/ ((double)job->width + job->height));
job->width *= scale;
job->height *= scale;
job->scale.x *= scale;
Owner: erg
Status: Fixed