/// <summary> /// Read a given number of bytes from the current stream position /// </summary> /// <param name="position">Position in the carrier stream</param> /// <param name="buffer">Byte array to populate while reading stream</param> /// <param name="offset">Zero-based byte offset in buffer at which to begin storing the data</param> /// <param name="count">The maximum number of bytes to be read from the current stream</param> /// <returns>The total number of bytes read into the buffer</returns> public override int Read(long position, byte[] buffer, int offset, int count) { int backingCount = count * 8 * _fileHeader.BytesPerPixel; BackingStream.Position = _fileHeader.BitmapOffset + (position * 8 * _fileHeader.BytesPerPixel); byte[] carrierValues = new byte[backingCount]; BackingStream.Read(carrierValues, 0, backingCount); int read = 0; int readIndex = 0; for (int i = 0, carrierIndex = 0; i < count * 8; ++i, carrierIndex += _fileHeader.BytesPerPixel) { read = read << 1; read |= carrierValues[carrierIndex] & 0x01; if (i == 0 || (i + 1) % 8 != 0) { continue; } buffer[readIndex + offset] = (byte)read; read = 0; ++readIndex; } return(readIndex); }
public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (!_hasWrittenPreReadByte) { _hasWrittenPreReadByte = true; var localBuffer = ArrayPool <byte> .Shared.Rent(count); try { var read = await BackingStream.ReadAsync(localBuffer, 0, count - 1); buffer[0] = _preReadByte; for (var i = 0; i < read; i++) { buffer[i + 1] = localBuffer[i]; } return(read + 1); } finally { ArrayPool <byte> .Shared.Return(localBuffer); } } return(await BackingStream.ReadAsync(buffer, offset, count)); }
/// <summary> /// Write a given number of bytes from the current stream position /// </summary> /// <param name="position">Position in the carrier stream</param> /// <param name="buffer">Byte array to write to the current stream position</param> /// <param name="offset">Zero-based byte offset in buffer at which to begin reading the data</param> /// <param name="count">The maximum number of bytes to be read from the buffer</param> public override void Write(long position, byte[] buffer, int offset, int count) { BackingStream.Position = position + HEADER_LENGTH; Logger.Debug(h => h("Write: Position = {0}, Offset = {1}, Count = {2}", BackingStream.Position, offset, count)); BackingStream.Write(buffer, offset, count); }
/// <summary> /// Read a given number of bytes from the current stream position /// </summary> /// <param name="position">Position in the carrier stream</param> /// <param name="buffer">Byte array to populate while reading stream</param> /// <param name="offset">Zero-based byte offset in buffer at which to begin storing the data</param> /// <param name="count">The maximum number of bytes to be read from the current stream</param> /// <returns>The total number of bytes read into the buffer</returns> public override int Read(long position, byte[] buffer, int offset, int count) { BackingStream.Position = position + HEADER_LENGTH; Logger.Debug(h => h("Read: Position = {0}, Offset = {1}, Count = {2}", BackingStream.Position, offset, count)); return(BackingStream.Read(buffer, offset, count)); }
public byte[] Read(long address, int length) { if (length == 0) { } byte[] result = new byte[length]; BackingStream.Seek(address, SeekOrigin.Begin); BackingStream.Read(result, 0, length); return(result); }
/// <summary> /// Free the stream instance /// </summary> public virtual void Dispose() { if (BackingStream == null) { return; } BackingStream.Flush(); _logger.Debug("Dispose"); BackingStream.Dispose(); BackingStream = null; }
/// <summary> /// Write a given number of bytes from the current stream position /// </summary> /// <param name="position">Position in the carrier stream</param> /// <param name="buffer">Byte array to write to the current stream position</param> /// <param name="offset">Zero-based byte offset in buffer at which to begin reading the data</param> /// <param name="count">The maximum number of bytes to be read from the buffer</param> /// <remarks> /// http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching /// </remarks> public override void Write(long position, byte[] buffer, int offset, int count) { int pixelCount = count * 8 * _fileHeader.BytesPerPixel; BackingStream.Position = _fileHeader.BitmapOffset + (position * 8 * _fileHeader.BytesPerPixel); byte[] pixels = new byte[pixelCount]; if (BackingStream.Read(pixels, 0, pixelCount) != pixelCount) { throw new InvalidOperationException( string.Format("Unable to read enough carrier pixels for writing, {0}bytes", pixelCount)); } int pixelIndex = 0; for (int i = 0; i < count; ++i) { //Reverse the byte, so the value isn't written backwards // http://stackoverflow.com/a/2602885 byte reverse = (byte)((buffer[offset + i] & 0xF0) >> 4 | (buffer[offset + i] & 0x0F) << 4); reverse = (byte)((reverse & 0xCC) >> 2 | (reverse & 0x33) << 2); reverse = (byte)((reverse & 0xAA) >> 1 | (reverse & 0x55) << 1); int writeIndex = 0; while (writeIndex < 8) { //http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching pixels[pixelIndex] = (byte)((pixels[pixelIndex] & ~0x01) | (-(reverse >> writeIndex++) & 0x01)); pixelIndex += _fileHeader.BytesPerPixel; } } BackingStream.Position = _fileHeader.BitmapOffset + (position * 8 * _fileHeader.BytesPerPixel); BackingStream.Write(pixels, 0, pixelCount); BackingStream.Flush(); }
public void Write(long address, byte[] bytes) { BackingStream.Seek(address, SeekOrigin.Begin); BackingStream.Write(bytes, 0, (int)bytes.Length); }
public Task CopyToAsync(Stream target, CancellationToken cancellationToken = default(CancellationToken)) => BackingStream.CopyToAsync(target);
public void CopyTo(Stream target) => BackingStream.CopyTo(target);
/// <summary> /// Clear the underlying buffer of the stream /// </summary> public virtual void Flush() { _logger.Debug("Flushing"); BackingStream.Flush(); }