public PixelStorageOptions CalculatePixelStorageOptions( ImageFormat outputFormat, PixelStorage storageMode, ImageDimensions imageDimensions, long totalBytes) { if (storageMode == PixelStorage.Auto) { long requiredBits = totalBytes * 8; long totalPixels = Math.BigMul(imageDimensions.Width, imageDimensions.Height * (imageDimensions.Frames ?? 1)); foreach (PixelStorage storage in new[] { PixelStorage.Low, PixelStorage.Medium, PixelStorage.High }) { PixelStorageOptions storageOptions = PixelStorageWithBitsPerChannel(outputFormat, storage); if (totalPixels * storageOptions.BitsPerPixel >= requiredBits) { return(storageOptions); } } return(PixelStorageWithBitsPerChannel(outputFormat, PixelStorage.High)); } return(PixelStorageWithBitsPerChannel(outputFormat, storageMode)); }
public virtual void Storage_InputStreamStoringInMostSignifcantBit() { byte[] embeddedData = { 100, 200, 250, 0, 5, 6, 10, 99 }; PixelStorageOptions storageOptions = new PixelStorageOptions(new[] { new PixelStorageOptions.ChannelStorageOptions(1, PixelStorageOptions.BitStorageMode.MostSignificantBits), }); var outputStream = new MemoryStream(); using (Stream pixelWriterStream = new PixelStorageWriterStream(outputStream, new MemoryStream(embeddedData), storageOptions, false)) { pixelWriterStream.WriteByte(255); byte[] output = outputStream.ToArray(); CollectionAssert.AreEqual( new byte[] { 228, 200, 250, 128, 133, 134, 138, 227 }, output); using (Stream imageReaderStream = new PixelStorageReaderStream(new MemoryStream(output), storageOptions, false)) { var decodedData = new MemoryStream(); imageReaderStream.CopyTo(decodedData); CollectionAssert.AreEqual(new byte[] { 255 }, decodedData.ToArray()); } } }
private ImageDimensions CalculateImageDimensions( Imaging.ImageFormat format, PixelStorageOptions storageOptions, ImageDimensions embeddedImageDimensions, long totalBytes, out int imageRepeats) { imageRepeats = 1; int bitsPerPixel = storageOptions == null ? format.BytesPerPixel * 8 : storageOptions.BitsPerPixel; long pixelsRequired = (long)Math.Ceiling(totalBytes / (bitsPerPixel / 8.0)); int frames; if (!format.SupportsFrames) { frames = 1; } else if (embeddedImageDimensions != null) { frames = embeddedImageDimensions.Frames ?? 1; } else { frames = (int)Math.Ceiling(pixelsRequired / Math.Pow(ImageWidthFrameThreshold, 2)); } int imageWidth; int imageHeight; if (embeddedImageDimensions != null) { imageWidth = embeddedImageDimensions.Width; imageHeight = embeddedImageDimensions.Height; } else { imageWidth = (int)Math.Floor(Math.Sqrt(pixelsRequired / frames)); imageHeight = (int)(pixelsRequired / (imageWidth * frames)); } while (Math.BigMul(imageHeight, (int)Math.Floor(imageWidth * (bitsPerPixel / 8.0) * frames)) <= totalBytes) { if (format.SupportsFrames) { imageRepeats++; frames += (embeddedImageDimensions != null ? embeddedImageDimensions.Frames : null) ?? 1; } else { imageHeight++; } } return(new ImageDimensions(format.SupportsFrames ? frames : (int?)null, imageWidth, imageHeight)); }
protected PixelStorageStream(Stream imageFormatterStream, PixelStorageOptions storageOptions, bool leaveOpen) { if (imageFormatterStream == null) { throw new ArgumentNullException("imageFormatterStream"); } if (storageOptions == null) { throw new ArgumentNullException("storageOptions"); } _imageFormatterStream = imageFormatterStream; _imageFormatterStreamStartPosition = _imageFormatterStream.Position; _storageOptions = storageOptions; _leaveOpen = leaveOpen; var byteChannelBits = new List <List <ByteChannelBits> >(); var currentByteChannelBits = new List <ByteChannelBits>(); int bitStart = 0; do { foreach (var channel in storageOptions.Channels) { currentByteChannelBits.Add(channel.StorageMode == PixelStorageOptions.BitStorageMode.LeastSignificantBits ? new ByteChannelBits(bitStart, channel.ByteMask, channel.Bits) : new ByteChannelBits(-(8 - channel.Bits - bitStart), channel.ByteMask, channel.Bits)); bitStart += channel.Bits; if (bitStart > 8) { throw new ArgumentException("The supplied pixel storage options must contain channels bit storages that squentially align to bytes", "storageOptions"); } else if (bitStart == 8) { byteChannelBits.Add(currentByteChannelBits); currentByteChannelBits = new List <ByteChannelBits>(); bitStart -= 8; } } } while (bitStart != 0); _unitChannelBits = byteChannelBits.Select(list => list.ToArray()).ToArray(); _bytesPerUnit = _unitChannelBits.Length; _channelBytesPerUnit = _unitChannelBits.SelectMany(channels => channels).Count(); _remainderBytes = new byte[_bytesPerUnit]; }
public PixelStorageWriterStream(Stream imageFormatterStream, Stream embeddedImagedDataStream, PixelStorageOptions storageOptions, bool leaveOpen, int bufferSize = 4096) : base(imageFormatterStream, storageOptions, leaveOpen) { if (embeddedImagedDataStream != null) { long bytesLeftInEmbeddedImage = embeddedImagedDataStream.Length - embeddedImagedDataStream.Position; if (bytesLeftInEmbeddedImage < Length) { embeddedImagedDataStream = new PaddedStream( embeddedImagedDataStream, paddingValue: 0, paddingLength: Length - bytesLeftInEmbeddedImage); } _embeddedImageDataStream = new BufferedStream(embeddedImagedDataStream, bufferSize); } else { _embeddedImageDataStream = new ConstantStream(0); } _bufferSize = bufferSize; }
public virtual async Task Storage_InputStreamThenOuputStreamProducesEquivalentData(Stream testData, PixelStorageOptions pixelStorageOptions, Stream image) { testData.Position = 0; var originalDataStream = new MemoryStream(); await testData.CopyToAsync(originalDataStream); originalDataStream.Position = 0; var pixelDataStream = new MemoryStream(); byte[] paddingBytes; using (var pixelWriterStream = new PixelStorageWriterStream(pixelDataStream, image, pixelStorageOptions, true)) { paddingBytes = new byte[pixelWriterStream.BytesPerUnit - originalDataStream.Length % pixelWriterStream.BytesPerUnit]; // Use an uneven write size to ensure remainder bytes are handled properly while (originalDataStream.Length != originalDataStream.Position) { foreach (int writeSize in writeSizes) { byte[] buffer = new byte[writeSize]; int totalBytesRead = 0; while (totalBytesRead < writeSize) { int bytesRead = await originalDataStream.ReadAsync(buffer, totalBytesRead, buffer.Length - totalBytesRead); if (bytesRead == 0) { break; } totalBytesRead += bytesRead; } await pixelWriterStream.WriteAsync(buffer, 0, totalBytesRead); } } await pixelWriterStream.WriteAsync(paddingBytes, 0, paddingBytes.Length); } var decodedData = new MemoryStream(); pixelDataStream.Position = 0; using (var imageReaderStream = new PixelStorageReaderStream(pixelDataStream, pixelStorageOptions, true)) { await imageReaderStream.CopyToAsync(decodedData, 4096); } byte[] expectedData = originalDataStream.ToArray().Concat(paddingBytes).ToArray(); var actualData = decodedData.ToArray(); if (!expectedData.SequenceEqual(actualData)) { CollectionAssert.AreEqual(expectedData, actualData); Assert.Fail(); } }
public PixelStorageReaderStream(Stream imageFormatterStream, PixelStorageOptions storageOptions, bool leaveOpen) : base(imageFormatterStream, storageOptions, leaveOpen) { }