Creating Palette based GIFs

A question was asked on the mailing list (ages ago) about creating 8-bit GIF files.  I proved this code for simple palette based GIFs, so here it is:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace Project
{
    class ProjectMain
    {
        public static void Main()
        {
            GenerateBackgroundImage(Color.AliceBlue, Color.Beige, Color.Cyan, 10, 10, 10, @"c:\image.gif");
        }

        public static void GenerateBackgroundImage(Color leftColour, Color centerColour,
            Color rightColour, int leftWidth, int centerWidth, int rightWidth, string path)
        {

            int width = leftWidth + centerWidth + rightWidth + 2;
            int height = 10;

            using (Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed))
            {
                Color backColour = Color.White;
                byte idxBackground = 0;
                byte idxLeft = 1;
                byte idxCenter = 2;
                byte idxRight = 3;

                ColorPalette cp = bitmap.Palette;
                cp.Entries[idxBackground] = backColour;
                cp.Entries[idxLeft] = leftColour;
                cp.Entries[idxCenter] = centerColour;
                cp.Entries[idxRight] = rightColour;

                bitmap.Palette = cp;

                fillrect(idxBackground, bitmap, new Rectangle(0, 0, width, height));
                fillrect(idxLeft, bitmap, new Rectangle(0, 0, leftWidth, height));
                fillrect(idxCenter, bitmap, new Rectangle(leftWidth + 1, 0, centerWidth, height));
                fillrect(idxRight, bitmap, new Rectangle(leftWidth + 2 + centerWidth, 0, rightWidth, height));

                bitmap.Save(path, ImageFormat.Gif);
            }
        }

        static void fillrect(byte colorIndex, Bitmap b, Rectangle r)
        {
            BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.WriteOnly, b.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            // This code is specific to a bitmap with 8 bits index per pixels.
            int bytes = b.Width * b.Height;
            byte[] Values = new byte[bytes];

            // Copy the RGB values into the array.
            Marshal.Copy(ptr, Values, 0, bytes);

            for (int y = r.Top; y < r.Bottom; y++)
            {
                for (int x = r.Left; x < r.Right; x++)
                {
                    Values[(y * b.Width) + x] = colorIndex;
                }
            }

            // Copy the values back to the bitmap
            Marshal.Copy(Values, 0, ptr, bytes);

            // Unlock the bits.
            b.UnlockBits(bmpData);
        }
    }
}

I would change fillrect, to seperate out the locking, and Marshal calls, to CreateTempBuffer, FillTempBuffer, and WriteTempBuffer functions, if you were to use fillrect more than a couple times.  But as it stands, the code is correct after each call.