// Load P5 PGM image (grayscale PNM image with binary encoding)
private static unsafe Bitmap ReadP5Image(Stream stream, int width, int height, int maxValue)
{
var scalingFactor = (double)255 / maxValue;
// create new bitmap and lock it
var image = Tools.CreateGrayscaleImage(width, height);
var imageData = image.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
var stride = imageData.Stride;
var ptr = (byte *)imageData.Scan0.ToPointer();
// prepare a buffer for one line
var line = new byte[width];
int totalBytesRead = 0, bytesRead = 0;
// load all rows
for (var y = 0; y < height; y++)
{
totalBytesRead = 0;
bytesRead = 0;
// load next line
while (totalBytesRead != width)
{
bytesRead = stream.Read(line, totalBytesRead, width - totalBytesRead);
if (bytesRead == 0)
{
// if we've reached the end before complete image is loaded, then there should
// be something wrong
throw new Exception();
}
totalBytesRead += bytesRead;
}
// fill next image row
var row = ptr + stride * y;
for (var x = 0; x < width; x++, row++)
{
*row = (byte)(scalingFactor * line[x]);
}
}
// unlock image and return it
image.UnlockBits(imageData);
return(image);
}