Here's an approach using Region, GraphicsPath, and GetRegionScans(). It should get you pretty close to an answer:

Code:
public partial class Form2 : Form
{
GraphicsPath gp = new GraphicsPath();
List<Rectangle> recs = new List<Rectangle>();
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
GraphicsPath redGP = new GraphicsPath();
Rectangle red = new Rectangle(new Point(12, 44), new Size(396, 323));
redGP.AddRectangle(red);
Region result = new Region(redGP);
List<Rectangle> subtractions = new List<Rectangle>();
subtractions.Add(new Rectangle(new Point(114, 99), new Size(77, 78)));
subtractions.Add(new Rectangle(new Point(92, 231), new Size(166, 66)));
subtractions.Add(new Rectangle(new Point(239, 27), new Size(140, 102)));
subtractions.Add(new Rectangle(new Point(348, 7), new Size(84, 96)));
foreach (Rectangle sub in subtractions)
{
GraphicsPath subGP = new GraphicsPath();
subGP.AddRectangle(sub);
Region subRgn = new Region(subGP);
result.Exclude(subRgn);
}
RectangleF[] scans = result.GetRegionScans(new Matrix());
gp.AddRectangles(scans);
gp.CloseAllFigures();
foreach (RectangleF recF in scans)
{
Rectangle r = Rectangle.Round(recF);
r.Inflate(-1, -1);
recs.Add(r);
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillPath(Brushes.Green, gp);
using(Pen p = new Pen(Brushes.Red, 5))
{
e.Graphics.DrawRectangle(p, Rectangle.Round(gp.GetBounds()));
}
foreach (Rectangle rec in recs)
{
e.Graphics.DrawRectangle(Pens.Black, rec);
}
}
}