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.