Tamaño de imagen .NET GDI + - limitaciones de códec de archivo

¿Existe un límite en el tamaño de la imagen que se puede codificar utilizando los códecs de archivos de imagen disponibles en .NET?

Estoy tratando de codificar imágenes> 4 GB de tamaño, pero simplemente no funciona (o no funciona correctamente, es decir, escribe un archivo ilegible) con .bmp, .jpg, .png o los codificadores .tif.

Cuando bajo el tamaño de la imagen a <2 GB, funciona con .jpg pero no con .bmp, .tif o .png.

Mi próximo intento sería probar libtiff porque sé que los archivos tiff están destinados a imágenes grandes.

¿Cuál es un buen formato de archivo para imágenes grandes? o solo estoy alcanzando las limitaciones de formato de archivo?

(Todo esto se realiza en un sistema operativo de 64 bits (WinXP 64) con 8 GB de RAM y se compila utilizando la arquitectura x64).

Random r = new Random((int)DateTime.Now.Ticks);

int width = 64000;
int height = 64000;
int stride = (width % 4) > 0 ? width + (width % 4) : width;
UIntPtr dataSize = new UIntPtr((ulong)stride * (ulong)height);
IntPtr p = Program.VirtualAlloc(IntPtr.Zero, dataSize, Program.AllocationType.COMMIT | Program.AllocationType.RESERVE, Program.MemoryProtection.READWRITE);

Bitmap bmp = new Bitmap(width, height, stride, PixelFormat.Format8bppIndexed, p);
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);

ColorPalette cp = bmp.Palette;
for (int i = 0; i < cp.Entries.Length; i++)
{
  cp.Entries[i] = Color.FromArgb(i, i, i);
}
bmp.Palette = cp;

unsafe
{
  for (int y = 0; y < bd.Height; y++)
  {
    byte* row = (byte*)bd.Scan0.ToPointer() + (y * bd.Stride);
    for (int x = 0; x < bd.Width; x++)
    {
      *(row + x) = (byte)r.Next(256);
    }
  }
}

bmp.UnlockBits(bd);
bmp.Save(@"c:\test.jpg", ImageFormat.Jpeg);
bmp.Dispose();

Program.VirtualFree(p, UIntPtr.Zero, 0x8000);

También he intentado usar una región de memoria GC fijada, pero esto está limitado a <2 GB.

Random r = new Random((int)DateTime.Now.Ticks);

int bytesPerPixel = 4;
int width = 4000;
int height = 4000;         
int padding = 4 - ((width * bytesPerPixel) % 4);
padding = (padding == 4 ? 0 : padding);
int stride = (width * bytesPerPixel) + padding;
UInt32[] pixels = new UInt32[width * height];
GCHandle gchPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned);
using (Bitmap bmp = new Bitmap(width, height, stride, PixelFormat.Format32bppPArgb, gchPixels.AddrOfPinnedObject()))
{
    for (int y = 0; y < height; y++)
    {
        int row = (y * width);
        for (int x = 0; x < width; x++)
        {
            pixels[row + x] = (uint)r.Next();
        }
    }

    bmp.Save(@"c:\test.jpg", ImageFormat.Jpeg);
}
gchPixels.Free();

Respuestas a la pregunta(3)

Su respuesta a la pregunta