/// <summary> /// Returns the offset of the next bit in the range /// [bitStart..bitEnd] that is different from the /// specified color. The end, bitEnd, is returned /// if no such bit exists. /// Like FindDifference, but also check the /// starting bit against the end in case start > end. /// </summary> /// <param name="reader">The reader.</param> /// <param name="bitStart">The offset of the start bit.</param> /// <param name="bitEnd">The offset of the end bit.</param> /// <param name="searchOne">If set to <c>true</c> searches "one" (i. e. white), otherwise searches black.</param> /// <returns>The offset of the first non-matching bit.</returns> private static uint FindDifferenceWithCheck(BitReader reader, uint bitStart, uint bitEnd, bool searchOne) { // Translated from LibTiff return((bitStart < bitEnd) ? FindDifference(reader, bitStart, bitEnd, searchOne) : bitEnd); }
/// <summary> /// 2d-encode a row of pixels. Consult the CCITT documentation for the algorithm. /// </summary> /// <param name="writer">The writer.</param> /// <param name="bytesFileOffset">Offset of image data in bitmap file.</param> /// <param name="imageBits">The bitmap file.</param> /// <param name="currentRow">Index of the current row.</param> /// <param name="referenceRow">Index of the reference row (0xffffffff if there is none).</param> /// <param name="width">The width of the image.</param> /// <param name="height">The height of the image.</param> /// <param name="bytesPerLineBmp">The bytes per line in the bitmap file.</param> static void FaxEncode2DRow(BitWriter writer, uint bytesFileOffset, byte[] imageBits, uint currentRow, uint referenceRow, uint width, uint height, uint bytesPerLineBmp) { // Translated from LibTiff uint bytesOffsetRead = bytesFileOffset + (height - 1 - currentRow) * bytesPerLineBmp; BitReader reader = new BitReader(imageBits, bytesOffsetRead, width); BitReader readerReference; if (referenceRow != 0xffffffff) { uint bytesOffsetReadReference = bytesFileOffset + (height - 1 - referenceRow) * bytesPerLineBmp; readerReference = new BitReader(imageBits, bytesOffsetReadReference, width); } else { byte[] tmpImageBits = new byte[bytesPerLineBmp]; for (int i = 0; i < bytesPerLineBmp; ++i) { tmpImageBits[i] = 255; } readerReference = new BitReader(tmpImageBits, 0, width); } uint a0 = 0; uint a1 = !reader.GetBit(0) ? 0 : FindDifference(reader, 0, width, true); uint b1 = !readerReference.GetBit(0) ? 0 : FindDifference(readerReference, 0, width, true); // ReSharper disable TooWideLocalVariableScope uint a2, b2; // ReSharper restore TooWideLocalVariableScope for (;;) { b2 = FindDifferenceWithCheck(readerReference, b1, width, readerReference.GetBit(b1)); if (b2 >= a1) { int d = (int)b1 - (int)a1; if (!(-3 <= d && d <= 3)) { /* horizontal mode */ a2 = FindDifferenceWithCheck(reader, a1, width, reader.GetBit(a1)); writer.WriteTableLine(HorizontalCodes, 0); if (a0 + a1 == 0 || reader.GetBit(a0)) { WriteSample(writer, a1 - a0, true); WriteSample(writer, a2 - a1, false); } else { WriteSample(writer, a1 - a0, false); WriteSample(writer, a2 - a1, true); } a0 = a2; } else { /* vertical mode */ writer.WriteTableLine(VerticalCodes, (uint)(d + 3)); a0 = a1; } } else { /* pass mode */ writer.WriteTableLine(PassCodes, 0); a0 = b2; } if (a0 >= width) { break; } bool bitA0 = reader.GetBit(a0); a1 = FindDifference(reader, a0, width, bitA0 /*reader.GetBit(a0)*/); b1 = FindDifference(readerReference, a0, width, !bitA0 /*reader.GetBit(a0)*/); b1 = FindDifferenceWithCheck(readerReference, b1, width, bitA0 /*reader.GetBit(a0)*/); } }
/// <summary> /// Returns the offset of the next bit in the range /// [bitStart..bitEnd] that is different from the /// specified color. The end, bitEnd, is returned /// if no such bit exists. /// </summary> /// <param name="reader">The reader.</param> /// <param name="bitStart">The offset of the start bit.</param> /// <param name="bitEnd">The offset of the end bit.</param> /// <param name="searchOne">If set to <c>true</c> searches "one" (i. e. white), otherwise searches black.</param> /// <returns>The offset of the first non-matching bit.</returns> private static uint FindDifference(BitReader reader, uint bitStart, uint bitEnd, bool searchOne) { // Translated from LibTiff reader.SetPosition(bitStart); return(bitStart + (searchOne ? CountOneBits(reader, bitEnd - bitStart) : CountZeroBits(reader, bitEnd - bitStart))); }