private void WriteCode(uint codeLength, uint code, Span <byte> compressedData) { while (codeLength > 0) { int bitNumber = (int)codeLength; bool bit = (code & (1 << (bitNumber - 1))) != 0; if (bit) { BitWriterUtils.WriteBit(compressedData, this.bytePosition, this.bitPosition); } else { BitWriterUtils.WriteZeroBit(compressedData, this.bytePosition, this.bitPosition); } this.bitPosition++; if (this.bitPosition == 8) { this.bytePosition++; this.bitPosition = 0; } codeLength--; } }
private void WritePixelRun(Span <byte> buffer, T4BitReader bitReader, uint bitsWritten) { if (bitReader.IsWhiteRun) { BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.whiteValue); } else { BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.blackValue); } }
/// <inheritdoc/> protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span <byte> buffer) { if (this.faxCompressionOptions.HasFlag(FaxCompressionOptions.TwoDimensionalCoding)) { TiffThrowHelper.ThrowNotSupported("TIFF CCITT 2D compression is not yet supported"); } bool eolPadding = this.faxCompressionOptions.HasFlag(FaxCompressionOptions.EolPadding); using var bitReader = new T4BitReader(stream, this.FillOrder, byteCount, this.Allocator, eolPadding); buffer.Clear(); uint bitsWritten = 0; uint pixelWritten = 0; while (bitReader.HasMoreData) { bitReader.ReadNextRun(); if (bitReader.RunLength > 0) { this.WritePixelRun(buffer, bitReader, bitsWritten); bitsWritten += bitReader.RunLength; pixelWritten += bitReader.RunLength; } if (bitReader.IsEndOfScanLine) { // Write padding bytes, if necessary. uint pad = 8 - (bitsWritten % 8); if (pad != 8) { BitWriterUtils.WriteBits(buffer, (int)bitsWritten, pad, 0); bitsWritten += pad; } pixelWritten = 0; } } // Edge case for when we are at the last byte, but there are still some unwritten pixels left. if (pixelWritten > 0 && pixelWritten < this.width) { bitReader.ReadNextRun(); this.WritePixelRun(buffer, bitReader, bitsWritten); } }
/// <inheritdoc/> protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span <byte> buffer) { using var bitReader = new ModifiedHuffmanBitReader(stream, this.FillOrder, byteCount, this.Allocator); buffer.Clear(); uint bitsWritten = 0; uint pixelsWritten = 0; while (bitReader.HasMoreData) { bitReader.ReadNextRun(); if (bitReader.RunLength > 0) { if (bitReader.IsWhiteRun) { BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.whiteValue); } else { BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.blackValue); } bitsWritten += bitReader.RunLength; pixelsWritten += bitReader.RunLength; } if (pixelsWritten == this.Width) { bitReader.StartNewRow(); pixelsWritten = 0; // Write padding bits, if necessary. uint pad = 8 - (bitsWritten % 8); if (pad != 8) { BitWriterUtils.WriteBits(buffer, (int)bitsWritten, pad, 0); bitsWritten += pad; } } if (pixelsWritten > this.Width) { TiffThrowHelper.ThrowImageFormatException("ccitt compression parsing error, decoded more pixels then image width"); } } }
private uint WriteScanLine(Span <byte> buffer, Span <byte> scanLine, uint bitsWritten) { byte white = (byte)(this.isWhiteZero ? 0 : 255); for (int i = 0; i < scanLine.Length; i++) { BitWriterUtils.WriteBits(buffer, (int)bitsWritten, 1, scanLine[i] == white ? this.whiteValue : this.blackValue); bitsWritten++; } // Write padding bytes, if necessary. uint remainder = bitsWritten % 8; if (remainder != 0) { uint padding = 8 - remainder; BitWriterUtils.WriteBits(buffer, (int)bitsWritten, padding, 0); bitsWritten += padding; } return(bitsWritten); }