Accord.Imaging.Formats.FITSCodec.ReadImageFrame C# (CSharp) Method

ReadImageFrame() private static method

private static ReadImageFrame ( Stream stream, FITSImageInfo imageInfo ) : Bitmap
stream Stream
imageInfo FITSImageInfo
return System.Drawing.Bitmap
        private static 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;
        }