// Read image frame from the specified stream (current stream's position is used)
private unsafe Bitmap ReadImageFrame(Stream stream, FITSImageInfo imageInfo)
{
int width = imageInfo.Width;
int height = imageInfo.Height;
// create new bitmap
Bitmap image = (imageInfo.BitsPerPixel == 8) ?
Tools.CreateGrayscaleImage(width, height) :
new Bitmap(width, height, PixelFormat.Format16bppGrayScale);
// lock it
BitmapData imageData = image.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadWrite, image.PixelFormat);
int originalBitsPerPixel = imageInfo.OriginalBitsPerPixl;
int stride = imageData.Stride;
byte *ptr = (byte *)imageData.Scan0.ToPointer( );
double min = imageInfo.MinDataValue;
double max = imageInfo.MaxDataValue;
// check number of bits per pixel and load image appropriately
if (imageInfo.BitsPerPixel == 16)
{
// 16 bpp grayscale image
double coef = 65535.0 / (max - min);
// prepare a buffer for one line
int lineSize = width * Math.Abs(originalBitsPerPixel) / 8;
byte[] line = new byte[lineSize];
byte[] temp = new byte[8];
// load all rows
for (int y = height - 1; y >= 0; y--)
{
// load next line
if (Tools.ReadStream(stream, line, 0, lineSize) < lineSize)
{
throw new ArgumentException("The stream does not contain valid FITS image.");
}
// fill next image row
ushort *row = (ushort *)(ptr + stride * y);
for (int x = 0, i = 0; x < width; x++, row++)
{
double value = 0;
switch (originalBitsPerPixel)
{
case 16: // 16 bit signed integer
{
short tempValue = 0;
unchecked
{
tempValue = (short)((line[i++] << 8) + line[i++]);
}
value = tempValue;
break;
}
case 32: // 32 bit signed integer
{
temp[3] = line[i++];
temp[2] = line[i++];
temp[1] = line[i++];
temp[0] = line[i++];
value = BitConverter.ToInt32(temp, 0);
break;
}
case -32: // 32 bit float
{
temp[3] = line[i++];
temp[2] = line[i++];
temp[1] = line[i++];
temp[0] = line[i++];
value = BitConverter.ToSingle(temp, 0);
break;
}
case -64: // 64 bit double
{
temp[7] = line[i++];
temp[6] = line[i++];
temp[5] = line[i++];
temp[4] = line[i++];
temp[3] = line[i++];
temp[2] = line[i++];
temp[1] = line[i++];
temp[0] = line[i++];
value = BitConverter.ToDouble(temp, 0);
break;
}
}
*row = (ushort)((value - min) * coef);
}
}
}
else
{
// 8 bpp grayscale image
double coef = 255.0 / (max - min);
// prepare a buffer for one line
byte[] line = new byte[width];
// load all rows
for (int y = height - 1; y >= 0; y--)
{
// load next line
if (Tools.ReadStream(stream, line, 0, width) < width)
{
throw new ArgumentException("The stream does not contain valid FITS image.");
}
// fill next image row
byte *row = ptr + stride * y;
for (int x = 0; x < width; x++, row++)
{
*row = (byte)(((double)line[x] - min) * coef);
}
}
}
// unlock image and return it
image.UnlockBits(imageData);
return(image);
}