internal Dimensions(byte[] buffer) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (Dimensions.MinHeaderSize > buffer.Length) { throw new ArgumentException($"Must contain at at least {Dimensions.MinHeaderSize} bytes.", nameof(buffer)); } this.Height = Jpeg.ReadLength(buffer, 1); this.Width = Jpeg.ReadLength(buffer, 3); }
/// <summary> /// Reads the passed stream and returns the jpeg image dimensions in pixels. /// It stops reading the stream when the dimensions are found. /// </summary> /// <param name="jpegStream"></param> /// <exception cref="InvalidJpegException">This exception is thrown when the passed stream does not conform to the jpeg standard.</exception> /// <exception cref="StreamTooSmallException">This exception is thrown when the passed stream does not contain the required jpeg headers before the end of the stream.</exception> /// <exception cref="BadSegmentSizeException">This exception is thrown when an attempt to recover from a bad segment size fails due to not finding a section marker before the end of the stream.</exception> /// <returns>the image dimensions in pixels</returns> public static Dimensions GetDimensions(Stream jpegStream) { Jpeg.ThrowIfNotJpeg(jpegStream); Dimensions imageDetails = new Dimensions(); byte[] headerBuffer = new byte[4]; do { Jpeg.CheckedRead(jpegStream, headerBuffer); if (headerBuffer[0] != Jpeg.SectionStartMarker) { Jpeg.FindNextSegment(jpegStream, headerBuffer); } ushort length = Jpeg.ReadLength(headerBuffer, 2); //TODO make this a seek if we do not need to read the data byte[] headerData = new byte[length - 2]; Jpeg.CheckedRead(jpegStream, headerData); if (headerBuffer[1] == Markers.SOF0 || headerBuffer[1] == Markers.SOF2) { imageDetails = new Dimensions(headerData); } }while (headerBuffer[1] != Markers.SOS && imageDetails.Height == 0); if (imageDetails.Height == 0) { // because it has no Start Of Frame header throw new InvalidJpegException("Failed to find Start Of Frame header."); } return(imageDetails); }