/// <summary> /// Creates a new object that is a copy of the current instance. /// </summary> /// /// <returns>A new object that is a copy of this instance.</returns> /// public override object Clone( ) { PNMImageInfo clone = new PNMImageInfo(width, height, bitsPerPixel, frameIndex, totalFrames); clone.version = version; clone.maxDataValue = maxDataValue; return(clone); }
/// <summary> /// Open specified stream. /// </summary> /// /// <param name="stream">Stream to open.</param> /// /// <returns>Returns number of images found in the specified stream.</returns> /// /// <exception cref="FormatException">Not a PNM image format.</exception> /// <exception cref="NotSupportedException">Format of the PNM image is not supported.</exception> /// <exception cref="ArgumentException">The stream contains invalid (broken) PNM image.</exception> /// public int Open(Stream stream) { // close previous decoding Close( ); this.imageInfo = ReadHeader(stream); this.stream = stream; this.dataPosition = stream.Seek(0, SeekOrigin.Current); return(imageInfo.TotalFrames); }
// Read and process PNM header. After the header is read stream pointer will // point to data. private PNMImageInfo ReadHeader(Stream stream) { // read magic word byte magic1 = (byte)stream.ReadByte( ); byte magic2 = (byte)stream.ReadByte( ); // check if it is valid PNM image if ((magic1 != 'P') || (magic2 < '1') || (magic2 > '6')) { throw new FormatException("The stream does not contain PNM image."); } // check if it is P5 or P6 format if ((magic2 != '5') && (magic2 != '6')) { throw new NotSupportedException("Format is not supported yet. Only P5 and P6 are supported for now."); } int width = 0, height = 0, maxValue = 0; try { // read image's width and height width = ReadIntegerValue(stream); height = ReadIntegerValue(stream); // read pixel's highiest value maxValue = ReadIntegerValue(stream); } catch { throw new ArgumentException("The stream does not contain valid PNM image."); } // check if all attributes are valid if ((width <= 0) || (height <= 0) || (maxValue <= 0)) { throw new ArgumentException("The stream does not contain valid PNM image."); } // check maximum pixel's value if (maxValue > 255) { throw new NotSupportedException("255 is the maximum pixel's value, which is supported for now."); } // prepare image information PNMImageInfo imageInfo = new PNMImageInfo(width, height, (magic2 == '5') ? 8 : 24, 0, 1); imageInfo.Version = (int)(magic2 - '0'); imageInfo.MaxDataValue = maxValue; return(imageInfo); }
/// <summary> /// Decode specified frame. /// </summary> /// /// <param name="frameIndex">Image frame to decode.</param> /// <param name="imageInfo">Receives information about decoded frame.</param> /// /// <returns>Returns decoded frame.</returns> /// /// <exception cref="NullReferenceException">No image stream was opened previously.</exception> /// <exception cref="ArgumentOutOfRangeException">Stream does not contain frame with specified index.</exception> /// <exception cref="ArgumentException">The stream contains invalid (broken) PNM image.</exception> /// public Bitmap DecodeFrame(int frameIndex, out ImageInfo imageInfo) { // check requested frame index if (frameIndex != 0) { throw new ArgumentOutOfRangeException("Currently opened stream does not contain frame with specified index."); } // seek to the required frame stream.Seek(dataPosition, SeekOrigin.Begin); // read required frame Bitmap image = ReadImageFrame(stream, this.imageInfo); // provide also frame information imageInfo = (PNMImageInfo)this.imageInfo.Clone( ); return(image); }
// Read image frame from the specified stream (current stream's position is used) private Bitmap ReadImageFrame(Stream stream, PNMImageInfo imageInfo) { try { // decode PNM image depending on its format switch (imageInfo.Version) { case 5: return(ReadP5Image(stream, imageInfo.Width, imageInfo.Height, imageInfo.MaxDataValue)); case 6: return(ReadP6Image(stream, imageInfo.Width, imageInfo.Height, imageInfo.MaxDataValue)); } } catch { throw new ArgumentException("The stream does not contain valid PNM image."); } return(null); }
/// <summary> /// Close decoding of previously opened stream. /// </summary> /// /// <remarks><para>The method does not close stream itself, but just closes /// decoding cleaning all associated data with it.</para></remarks> /// public void Close( ) { stream = null; imageInfo = null; }
/// <summary> /// Decode first frame of PNM image. /// </summary> /// /// <param name="stream">Source stream, which contains encoded image.</param> /// /// <returns>Returns decoded image frame.</returns> /// /// <exception cref="FormatException">Not a PNM image format.</exception> /// <exception cref="NotSupportedException">Format of the PNM image is not supported.</exception> /// <exception cref="ArgumentException">The stream contains invalid (broken) PNM image.</exception> /// public Bitmap DecodeSingleFrame(Stream stream) { PNMImageInfo imageInfo = ReadHeader(stream); return(ReadImageFrame(stream, imageInfo)); }