Bug 41040 - OutOfMemoryException with simple path based IntersectClip()
Summary: OutOfMemoryException with simple path based IntersectClip()
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.Drawing ()
Version: 4.2.0 (C6)
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-05-11 20:32 UTC by Stephen Darnell
Modified: 2016-05-11 20:32 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 41040 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
NEW

Description Stephen Darnell 2016-05-11 20:32:01 UTC
Description of Problem:
A simple app that draws to an offscreen bitmap crashes throws OutOfMemoryException when setting a simple rectangle (albeit path based clip). Exception occurs in Graphics.IntersectClip(). With the message:

** (process:88288): WARNING **: Path conversion requested 64000000 bytes (4000 x 4000). Maximum size is 8388608 bytes.

Whilst this case uses a bitmap of 4000x4000, images of 1450x1450 hit the limit.

Though with other test cases the message is different (complaining that the region requires too much memory).

Note that the initial clip rect is a simple rectangle (size of bitmap), and the region being passed to the IntersectClip() a single simple rectangle.
It is really unfortunate that this case forces conversion to some sort of bitmap region.

Steps to reproduce the problem:
1. Create a simple console app, and insert this code, and run:

using System;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace MonoClipBug
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var bitmap = new Bitmap(4000, 4000);
            var g = Graphics.FromImage(bitmap);
            dumpRegion(g.Clip, "Fresh Graphics");
            Console.WriteLine("VisibleClipBounds = {0}", g.VisibleClipBounds);

            // Without this SetClip() there's a SIGSEGV crash (raised separately)
            g.SetClip(new Rectangle(0,0, 4000,4000));

            g.TranslateTransform(4040, 463);
            dumpRegion(g.Clip, "After translation");

            GraphicsPath p = new GraphicsPath();

            p.AddLine(4, 4, 680, 4);
            p.AddLine(680, 4, 680, 430);
            p.AddLine(680, 430, 4, 430);
            p.CloseFigure();

            var r = new Region(p);
            dumpRegion(r, "Path region");
            g.IntersectClip(r);
            dumpRegion(g.Clip, "After IntersectClip");
        }

        private static void dumpRegion(Region r, string prefix)
        {
            var scans = r.GetRegionScans(new Matrix());
            Console.WriteLine("{0} Region scans {1}", prefix, scans.Length);
            foreach (var s in scans) Console.WriteLine(" scan {0}", s);
        }
    }
}

Actual Results:

Loaded assembly: /Library/Frameworks/Mono.framework/Versions/4.2.3/lib/mono/gac/System.Drawing/4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/4.2.3/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll
Fresh Graphics Region scans 1
 scan {X=-4194304,Y=-4194304,Width=8388608,Height=8388608}
VisibleClipBounds = {X=0,Y=0,Width=4000,Height=4000}
After translation Region scans 1
 scan {X=-4040,Y=-463,Width=4000,Height=4000}
Path region Region scans 1
 scan {X=4,Y=4,Width=676,Height=426}

** (process:88288): WARNING **: Path conversion requested 64000000 bytes (4000 x 4000). Maximum size is 8388608 bytes.

With OutOfMemoryException being thrown from Graphics.IntersectClip().
System.Drawing.GDIPlus.CheckStatus(System.Drawing.Status status) in /private/tmp/source-mono-4.2.3/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.3/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs:215
System.Drawing.Graphics.IntersectClip(System.Drawing.Region region) in /private/tmp/source-mono-4.2.3/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.3/mcs/class/System.Drawing/System.Drawing/Graphics.cs:1812
MonoClipBug.MainClass.Main(string[] args) in /Users/me/Projects/MonoClipBug/MonoClipBug/Program.cs:31

Expected results (same code running on Windows 7):

Fresh Graphics Region scans 1
 scan {X=-4194304,Y=-4194304,Width=8388608,Height=8388608}
VisibleClipBounds = {X=0,Y=0,Width=4000,Height=4000}
After translation Region scans 1
 scan {X=-4040,Y=-463,Width=4000,Height=4000}
Path region Region scans 1
 scan {X=4,Y=4,Width=676,Height=426}
After IntersectClip Region scans 0

How often does this happen? 

Very frequently for my app which draws components, where before drawing each component we translate and clip to the component.
Other cases occur even when not using the simple square path region.

Additional Information:

Related to: https://bugzilla.xamarin.com/show_bug.cgi?id=41036