ReadStream() public static method

Read specified amount of bytes from the specified stream.

This tool function guarantees that requested number of bytes was read from the source stream (.NET streams don't guarantee this and may return less bytes than it was requested). Only in the case if end of stream was reached, the function may return with less bytes read.

public static ReadStream ( Stream stream, byte buffer, int offset, int count ) : int
stream Stream Source sream to read data from.
buffer byte Buffer to read data into.
offset int Offset in buffer to put data into.
count int Number of bytes to read.
return int
Example #1
0
        // Read image frame from the specified stream (current stream's position is used)
        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);
        }
Example #2
0
        // Read and process FITS header. After the header is read stream pointer will
        // point to data or extension.
        private static FITSImageInfo ReadHeader(Stream stream)
        {
            byte[] headerRecord   = new byte[80];
            int    recordsRead    = 1;
            bool   endKeyWasFound = false;

            FITSImageInfo imageInfo = new FITSImageInfo();

            // read first record and check for correct image
            if (
                (Tools.ReadStream(stream, headerRecord, 0, 80) < 80) ||
                (Encoding.UTF8.GetString(headerRecord, 0, 8) != "SIMPLE  "))
            {
                throw new FormatException("The stream does not contatin FITS image.");
            }
            else
            {
                // check if the image has standard FITS format
                if (Encoding.UTF8.GetString(headerRecord, 10, 70).Split('/')[0].Trim() != "T")
                {
                    throw new NotSupportedException("The stream contains not standard FITS data file.");
                }
            }

            // read header and locate data block
            while (true)
            {
                // read next record
                if (Tools.ReadStream(stream, headerRecord, 0, 80) < 80)
                {
                    throw new ArgumentException("The stream does not contain valid FITS image.");
                }
                recordsRead++;

                // get keyword
                string keyword = Encoding.UTF8.GetString(headerRecord, 0, 8);

                // skip commenct and history
                if ((keyword == "COMMENT ") || (keyword == "HISTORY "))
                {
                    continue;
                }

                // check if it is end of header keyword
                if (keyword == "END     ")
                {
                    endKeyWasFound = true;
                }

                if (endKeyWasFound)
                {
                    if (recordsRead % 36 == 0)
                    {
                        // found data or extension header

                        // make a small check of some header values
                        if ((imageInfo.BitsPerPixel == 0) || (imageInfo.Width == 0) || (imageInfo.Height == 0))
                        {
                            imageInfo.TotalFrames = 0;
                        }

                        // let's return here and let other routines process data
                        break;
                    }
                }
                else
                {
                    // get string representation of value/comments
                    string strValue = Encoding.UTF8.GetString(headerRecord, 10, 70);

                    // check important keywords
                    if (keyword == "BITPIX  ")
                    {
                        int value = ExtractIntegerValue(strValue);

                        if ((value != 8) && (value != 16) && (value != 32) && (value != -32) && (value != -64))
                        {
                            throw new NotSupportedException("Data format (" + value + ") is not supported.");
                        }

                        // bits per pixel
                        imageInfo.BitsPerPixel        = (value == 8) ? 8 : 16;
                        imageInfo.OriginalBitsPerPixl = value;
                    }
                    else if (Encoding.UTF8.GetString(headerRecord, 0, 5) == "NAXIS")
                    {
                        // information about data axis
                        int value = ExtractIntegerValue(strValue);

                        // check axis
                        switch (headerRecord[5])
                        {
                        // number of axis
                        case (byte)' ':
                            switch (value)
                            {
                            case 1:
                            default:
                                throw new NotSupportedException("FITS files with data dimension of " + value + " are not supported.");

                            case 0:
                                // the stream does not have an image, do nothing
                                break;

                            case 2:
                                // the stream has 1 2D image
                                imageInfo.TotalFrames = 1;
                                break;

                            case 3:
                                // the stream has 3D image - series of 2D images
                                break;
                            }
                            break;

                        // length of 1st axis
                        case (byte)'1':
                            imageInfo.Width = value;
                            break;

                        // length of 2nd axis
                        case (byte)'2':
                            imageInfo.Height = value;
                            break;

                        // length of 3rd axis
                        case (byte)'3':
                            imageInfo.TotalFrames = value;
                            break;
                        }
                    }
                    else if (keyword == "TELESCOP")
                    {
                        imageInfo.Telescope = ExtractStringValue(strValue);
                    }
                    else if (keyword == "OBJECT  ")
                    {
                        imageInfo.Object = ExtractStringValue(strValue);
                    }
                    else if (keyword == "OBSERVER")
                    {
                        imageInfo.Observer = ExtractStringValue(strValue);
                    }
                    else if (keyword == "INSTRUME")
                    {
                        imageInfo.Instrument = ExtractStringValue(strValue);
                    }

                    // --- for debugging ---

                    /* if ( keyword[0] != ' ' )
                     * {
                     *  System.Diagnostics.Debug.Write( keyword );
                     *  if ( headerRecord[8] == '=' )
                     *  {
                     *      System.Diagnostics.Debug.WriteLine( " = " + strValue );
                     *  }
                     *  else
                     *  {
                     *      System.Diagnostics.Debug.WriteLine( "" );
                     *  }
                     * } */
                    // --- ---
                }
            }

            // scan all available data to find minimum and maximum values,
            // which will be used for scaling. the scan is done here (not while
            // reading actual frame) because FITS file may have set of images
            // packed into data cube, so entire scan of all the data is required.

            // if is stream is seekable
            if (!stream.CanSeek)
            {
                throw new ArgumentException("The stream must be seekable.");
            }

            // remember current position
            long dataPos = stream.Seek(0, SeekOrigin.Current);

            // data size
            int lineLength           = imageInfo.Width * (Math.Abs(imageInfo.OriginalBitsPerPixl) / 8);
            int totalLines           = imageInfo.Height * imageInfo.TotalFrames;
            int originalBitsPerPixel = imageInfo.OriginalBitsPerPixl;

            byte[] buffer = new byte[lineLength];
            byte[] temp   = new byte[8];

            // min and max values
            double min = double.MaxValue;
            double max = double.MinValue;

            for (int i = 0; i < totalLines; i++)
            {
                // read next line
                if (Tools.ReadStream(stream, buffer, 0, lineLength) < lineLength)
                {
                    throw new ArgumentException("The stream does not contain valid FITS image.");
                }

                // scan the line
                for (int j = 0; j < lineLength;)
                {
                    double value = 0;

                    // read values accordint to their format
                    switch (originalBitsPerPixel)
                    {
                    case 8:        // 8 bit unsigned integer
                        value = buffer[j++];
                        break;

                    case 16:        // 16 bit signed integer
                    {
                        short tempValue = 0;
                        unchecked
                        {
                            tempValue = (short)((buffer[j++] << 8) | buffer[j++]);
                        }
                        value = tempValue;
                        break;
                    }

                    case 32:        // 32 bit signed integer
                    {
                        temp[3] = buffer[j++];
                        temp[2] = buffer[j++];
                        temp[1] = buffer[j++];
                        temp[0] = buffer[j++];

                        value = BitConverter.ToInt32(temp, 0);

                        break;
                    }

                    case -32:       // 32 bit float
                    {
                        temp[3] = buffer[j++];
                        temp[2] = buffer[j++];
                        temp[1] = buffer[j++];
                        temp[0] = buffer[j++];

                        value = BitConverter.ToSingle(temp, 0);
                        break;
                    }

                    case -64:       // 64 bit double
                    {
                        temp[7] = buffer[j++];
                        temp[6] = buffer[j++];
                        temp[5] = buffer[j++];
                        temp[4] = buffer[j++];
                        temp[3] = buffer[j++];
                        temp[2] = buffer[j++];
                        temp[1] = buffer[j++];
                        temp[0] = buffer[j++];

                        value = BitConverter.ToDouble(temp, 0);
                        break;
                    }
                    }

                    if (value > max)
                    {
                        max = value;
                    }
                    if (value < min)
                    {
                        min = value;
                    }
                }
            }

            imageInfo.MaxDataValue = max;
            imageInfo.MinDataValue = min;

            // restore stream position to the begining of data
            stream.Seek(dataPos, SeekOrigin.Begin);

            return(imageInfo);
        }