Hi, 
I'm trying to convert a FreeType2 bitmap to a System::Drawing::Bitmap in C++/CLI.
FT_Bitmap has a unsigned char* buffer that contains the data to write.
I have got somewhat working save it disk as a *.tga, but when saving as *.bmp it renders incorrectly.
I believe that the size of byte[] is incorrect and that my data is truncated. 
Any hints/tips/ideas on what is going on here would be greatly appreciated. Links to articles explaining byte layout and pixel formats etc. would be helpful.
Thanks!!
C++/CLI code. 
  FT_Bitmap *bitmap = &face->glyph->bitmap;
  int width = (face->bitmap->metrics.width / 64);
  int height = (face->bitmap->metrics.height / 64);
  // must be aligned on a 32 bit boundary or 4 bytes
  int depth = 8;
  int stride = ((width * depth + 31) & ~31) >> 3;
  int bytes = (int)(stride * height);
  // as *.tga
  void *buffer = bytes ? malloc(bytes) : NULL;
  if (buffer)
  {
    memset(buffer, 0, bytes);
    for (int i = 0; i < glyph->rows; ++i)
      memcpy((char *)buffer + (i * width), glyph->buffer + (i * glyph->pitch), glyph->pitch);
    WriteTGA("Test.tga", buffer, width, height);              
  }
  array<Byte>^ values = gcnew array<Byte>(bytes);  
  Marshal::Copy((IntPtr)glyph->buffer, values, 0, bytes);
  // as *.bmp
  Bitmap^ systemBitmap = gcnew Bitmap(width, height, PixelFormat::Format24bppRgb);
  // create bitmap data, lock pixels to be written.
  BitmapData^ bitmapData = systemBitmap->LockBits(Rectangle(0, 0, width, height), ImageLockMode::WriteOnly, bitmap->PixelFormat);
  Marshal::Copy(values, 0, bitmapData->Scan0, bytes);
  systemBitmap->UnlockBits(bitmapData);
  systemBitmap->Save("Test.bmp");
Reference, FT_Bitmap
typedef struct  FT_Bitmap_
  {
    int             rows;
    int             width;
    int             pitch;
    unsigned char*  buffer;
    short           num_grays;
    char            pixel_mode;
    char            palette_mode;
    void*           palette;
  } FT_Bitmap;
Reference, WriteTGA
bool WriteTGA(const char *filename, void *pxl, uint16 width, uint16 height)
{
  FILE *fp = NULL;
  fopen_s(&fp, filename, "wb");
  if (fp)
  {
    TGAHeader header;
    memset(&header, 0, sizeof(TGAHeader));
    header.imageType = 3;
    header.width = width;
    header.height = height;
    header.depth = 8;
    header.descriptor = 0x20;
    fwrite(&header, sizeof(header), 1, fp);
    fwrite(pxl, sizeof(uint8) * width * height, 1, fp);
    fclose(fp);
    return true;
  }
  return false;
}