1using System.Drawing.Imaging;
2using System.Runtime.InteropServices;
6 internal static class SlideOverviewBuilder
8 internal static System.Drawing.Bitmap Build(
int width,
int height,
int tileWidth,
int tileHeight,
9 Func<
int,
int,
byte[]> readTile)
11 ArgumentOutOfRangeException.ThrowIfNegativeOrZero(width);
12 ArgumentOutOfRangeException.ThrowIfNegativeOrZero(height);
13 ArgumentOutOfRangeException.ThrowIfNegativeOrZero(tileWidth);
14 ArgumentOutOfRangeException.ThrowIfNegativeOrZero(tileHeight);
15 ArgumentNullException.ThrowIfNull(readTile);
16 var result =
new System.Drawing.Bitmap(width, height,
PixelFormat.Format32bppPArgb);
19 var pixels = result.LockBits(
new System.Drawing.Rectangle(0, 0, width, height),
20 ImageLockMode.WriteOnly,
PixelFormat.Format32bppPArgb);
23 int tileStride = checked(tileWidth * 4);
24 for (
int y = 0, row = 0; y < height; y += tileHeight, row++)
25 for (
int x = 0, column = 0; x < width; x += tileWidth, column++)
27 byte[] bytes = readTile(column, row);
28 if (bytes ==
null || bytes.Length != checked(tileStride * tileHeight))
29 throw new InvalidDataException(
"The overview tile does not match the slide tile dimensions.");
30 int copyWidth = Math.Min(tileWidth, width - x);
31 int copyHeight = Math.Min(tileHeight, height - y);
33 for (
int line = 0; line < copyHeight; line++)
34 Marshal.Copy(bytes, line * tileStride,
35 IntPtr.Add(pixels.Scan0, (y + line) * pixels.Stride + x * 4), copyWidth * 4);
40 result.UnlockBits(pixels);
OpenTK.Graphics.OpenGL.PixelFormat PixelFormat