private void CompressAndWriteClusters(long focusVcn, int count, byte[] buffer, int offset) { BlockCompressor compressor = _context.Options.Compressor; compressor.BlockSize = _bytesPerCluster; int compressedLength = _ioBuffer.Length; var result = compressor.Compress(buffer, offset, _attr.CompressionUnitSize * _bytesPerCluster, _ioBuffer, 0, ref compressedLength); if (result == CompressionResult.AllZeros) { _rawStream.ReleaseClusters(focusVcn, count); } else if (result == CompressionResult.Compressed && (_attr.CompressionUnitSize * _bytesPerCluster) - compressedLength > _bytesPerCluster) { int compClusters = Utilities.Ceil(compressedLength, _bytesPerCluster); _rawStream.AllocateClusters(focusVcn, compClusters); _rawStream.WriteClusters(focusVcn, compClusters, _ioBuffer, 0); _rawStream.ReleaseClusters(focusVcn + compClusters, _attr.CompressionUnitSize - compClusters); } else { _rawStream.AllocateClusters(focusVcn, _attr.CompressionUnitSize); _rawStream.WriteClusters(focusVcn, _attr.CompressionUnitSize, buffer, offset); } }
private int CompressAndWriteClusters(long focusVcn, int count, byte[] buffer, int offset) { BlockCompressor compressor = _context.Options.Compressor; compressor.BlockSize = _bytesPerCluster; int totalAllocated = 0; int compressedLength = _ioBuffer.Length; CompressionResult result = compressor.Compress(buffer, offset, _attr.CompressionUnitSize * _bytesPerCluster, _ioBuffer, 0, ref compressedLength); if (result == CompressionResult.AllZeros) { totalAllocated -= _rawStream.ReleaseClusters(focusVcn, count); } else if (result == CompressionResult.Compressed && _attr.CompressionUnitSize * _bytesPerCluster - compressedLength > _bytesPerCluster) { int compClusters = MathUtilities.Ceil(compressedLength, _bytesPerCluster); totalAllocated += _rawStream.AllocateClusters(focusVcn, compClusters); totalAllocated += _rawStream.WriteClusters(focusVcn, compClusters, _ioBuffer, 0); totalAllocated -= _rawStream.ReleaseClusters(focusVcn + compClusters, _attr.CompressionUnitSize - compClusters); } else { totalAllocated += _rawStream.AllocateClusters(focusVcn, _attr.CompressionUnitSize); totalAllocated += _rawStream.WriteClusters(focusVcn, _attr.CompressionUnitSize, buffer, offset); } return(totalAllocated); }
public void Compress1KBlockSize() { object instance = typeof(NtfsFileSystem).Assembly.CreateInstance("DiscUtils.Ntfs.LZNT1"); BlockCompressor compressor = (BlockCompressor)instance; int compressedLength = 16 * 4096; byte[] compressedData = new byte[compressedLength]; // Double-check, make sure native code round-trips byte[] nativeCompressed = NativeCompress(_uncompressedData, 0, _uncompressedData.Length, 1024); Assert.AreEqual(_uncompressedData, NativeDecompress(nativeCompressed, 0, nativeCompressed.Length)); compressor.BlockSize = 1024; CompressionResult r = compressor.Compress(_uncompressedData, 0, _uncompressedData.Length, compressedData, 0, ref compressedLength); Assert.AreEqual(CompressionResult.Compressed, r); byte[] duDecompressed = new byte[_uncompressedData.Length]; int numDuDecompressed = compressor.Decompress(compressedData, 0, compressedLength, duDecompressed, 0); byte[] rightSizedDuDecompressed = new byte[numDuDecompressed]; Array.Copy(duDecompressed, rightSizedDuDecompressed, numDuDecompressed); // Note: Due to bug in Windows LZNT1, we compare against native decompression, not the original data, since // Windows LZNT1 corrupts data on decompression when block size != 4096. Assert.AreEqual(rightSizedDuDecompressed, NativeDecompress(compressedData, 0, compressedLength)); }
public void CompressAllZeros() { object instance = typeof(NtfsFileSystem).Assembly.CreateInstance("DiscUtils.Ntfs.LZNT1"); BlockCompressor compressor = (BlockCompressor)instance; byte[] compressed = new byte[64 * 1024]; int numCompressed = 64 * 1024; Assert.AreEqual(CompressionResult.AllZeros, compressor.Compress(new byte[64 * 1024], 0, 64 * 1024, compressed, 0, ref numCompressed)); }
public void CompressionThrowsExceptionWhenImageHasInvalidDimensions() { var compressor = new BlockCompressor(); var format = new Mock <IBlockCompressionFormat>(); var bitmap = new Mock <IUncompressedImage>(); bitmap.Setup(b => b.Width).Returns(10); bitmap.Setup(b => b.Height).Returns(16); Assert.Throws <InvalidOperationException>(() => compressor.Compress(bitmap.Object, format.Object)); }
public void CompressIncompressible() { object instance = typeof(NtfsFileSystem).Assembly.CreateInstance("DiscUtils.Ntfs.LZNT1"); BlockCompressor compressor = (BlockCompressor)instance; Random rng = new Random(6324); byte[] uncompressed = new byte[64 * 1024]; rng.NextBytes(uncompressed); byte[] compressed = new byte[64 * 1024]; int numCompressed = 64 * 1024; Assert.AreEqual(CompressionResult.Incompressible, compressor.Compress(uncompressed, 0, uncompressed.Length, compressed, 0, ref numCompressed)); }
public void BlockCompressorShouldWorkAsExpected() { // Arrange const int threadsCount = 8; var strater = MockRepository.GenerateMock<IBlockCompressorStarter>(); strater.Expect(t => t.StartCompress(JobType.Compress)).Repeat.Times(threadsCount); var compressor = new BlockCompressor(threadsCount, strater); // Act compressor.Compress(JobType.Compress); // Assert strater.VerifyAllExpectations(); }
public void Compress() { object instance = typeof(NtfsFileSystem).Assembly.CreateInstance("DiscUtils.Ntfs.LZNT1"); BlockCompressor compressor = (BlockCompressor)instance; int compressedLength = 16 * 4096; byte[] compressedData = new byte[compressedLength]; // Double-check, make sure native code round-trips byte[] nativeCompressed = NativeCompress(_uncompressedData, 0, _uncompressedData.Length, 4096); Assert.AreEqual(_uncompressedData, NativeDecompress(nativeCompressed, 0, nativeCompressed.Length)); compressor.BlockSize = 4096; CompressionResult r = compressor.Compress(_uncompressedData, 0, _uncompressedData.Length, compressedData, 0, ref compressedLength); Assert.AreEqual(CompressionResult.Compressed, r); Assert.AreEqual(_uncompressedData, NativeDecompress(compressedData, 0, compressedLength)); Assert.Less(compressedLength, _uncompressedData.Length * 0.66); }
public void CompressMidDestBuffer() { object instance = CreateInstance <NtfsFileSystem>("DiscUtils.Ntfs.LZNT1"); BlockCompressor compressor = (BlockCompressor)instance; // Double-check, make sure native code round-trips byte[] nativeCompressed = NativeCompress(_uncompressedData, 0, _uncompressedData.Length, 4096); Assert.Equal(_uncompressedData, NativeDecompress(nativeCompressed, 0, nativeCompressed.Length)); int compressedLength = 128 * 1024; byte[] compressedData = new byte[compressedLength]; compressor.BlockSize = 4096; CompressionResult r = compressor.Compress(_uncompressedData, 0, _uncompressedData.Length, compressedData, 32 * 1024, ref compressedLength); Assert.Equal(CompressionResult.Compressed, r); Assert.True(compressedLength < _uncompressedData.Length); Assert.Equal(_uncompressedData, NativeDecompress(compressedData, 32 * 1024, compressedLength)); }
public void RunsCompressionForEachBlock() { const int byteCount = 8; var format = new Mock <IBlockCompressionFormat>(); format.Setup(f => f.BlockSize).Returns(byteCount); format.Setup(f => f.Compress(It.IsAny <Color[]>())).Returns(new byte[byteCount]); var compressor = new BlockCompressor(); compressor.Compress(CreateBitmapMock(), format.Object); format.Verify(f => f.Compress(It.IsAny <Color[]>()), Times.Exactly(6)); format.Verify(f => f.Compress(It.Is <Color[]>(colors => colors.All(c => c == Red)))); format.Verify(f => f.Compress(It.Is <Color[]>(colors => colors.All(c => c == Green)))); format.Verify(f => f.Compress(It.Is <Color[]>(colors => colors.All(c => c == Blue)))); format.Verify(f => f.Compress(It.Is <Color[]>(colors => colors.All(c => c == White)))); format.Verify(f => f.Compress(It.Is <Color[]>(colors => colors.All(c => c == Black)))); format.Verify(f => f.Compress(It.Is <Color[]>(colors => colors.All(c => c == Gray)))); }
public void Compress1KBlock() { object instance = typeof(NtfsFileSystem).Assembly.CreateInstance("DiscUtils.Ntfs.LZNT1"); BlockCompressor compressor = (BlockCompressor)instance; byte[] uncompressed1K = new byte[1024]; Array.Copy(_uncompressedData, uncompressed1K, 1024); int compressedLength = 1024; byte[] compressedData = new byte[compressedLength]; // Double-check, make sure native code round-trips byte[] nativeCompressed = NativeCompress(uncompressed1K, 0, 1024, 1024); Assert.AreEqual(uncompressed1K, NativeDecompress(nativeCompressed, 0, nativeCompressed.Length)); compressor.BlockSize = 1024; CompressionResult r = compressor.Compress(uncompressed1K, 0, 1024, compressedData, 0, ref compressedLength); Assert.AreEqual(CompressionResult.Compressed, r); Assert.AreEqual(uncompressed1K, NativeDecompress(compressedData, 0, compressedLength)); }
private void Compress() { if (Interlocked.CompareExchange(ref _compressState, 3, 1) != 1) { return; } _lock.EnterReadLock(); if (_mode == Empty) { return; } if (_array == null) { return; } IntervalTree <T> intervalTree = null; try { if (Width == Height) { var compressor = new BlockCompressor(Width); intervalTree = compressor.Compress(_array); } else { var compressor = new ColumnCompressor(Width, Height); intervalTree = compressor.Compress(_array); } } catch (Exception e) { Debug.LogError(e); } finally { _lock.ExitReadLock(); } try { if (intervalTree != null && _lock.TryEnterWriteLock(150)) { _intervalTree = intervalTree; _mode = Interval; var temp = _array; _array = null; for (var i = 0; i < temp.Length; i++) { temp[i] = default(T); } PoolManager.GetArrayPool <T[]>(_size).Push(temp); } } catch (Exception e) { Debug.LogError(e); } finally { _lock.ExitWriteLock(); Interlocked.Exchange(ref _lastTouched, DateTime.Now.Ticks); Interlocked.Exchange(ref _compressState, 0); } }