Example #1
0
 /// <summary>
 /// Encodes a bitonal bitmap using 1D CCITT fax encoding.
 /// </summary>
 /// <param name="imageData">Space reserved for the fax encoded bitmap. An exception will be thrown if this buffer is too small.</param>
 /// <param name="imageBits">The bitmap to be encoded.</param>
 /// <param name="bytesFileOffset">Offset of image data in bitmap file.</param>
 /// <param name="width">The width of the image.</param>
 /// <param name="height">The height of the image.</param>
 /// <returns>The size of the fax encoded image (0 on failure).</returns>
 private static int DoFaxEncoding(ref byte[] imageData, byte[] imageBits, uint bytesFileOffset, uint width, uint height)
 {
     try
     {
         uint bytesPerLineBmp = ((width + 31) / 32) * 4;
         BitWriter writer = new BitWriter(ref imageData);
         for (uint y = 0; y < height; ++y)
         {
             uint bytesOffsetRead = bytesFileOffset + (height - 1 - y) * bytesPerLineBmp;
             BitReader reader = new BitReader(imageBits, bytesOffsetRead, width);
             for (uint bitsRead = 0; bitsRead < width;)
             {
                 uint white = CountOneBits(reader, width - bitsRead);
                 WriteSample(writer, white, true);
                 bitsRead += white;
                 if (bitsRead < width)
                 {
                     uint black = CountZeroBits(reader, width - bitsRead);
                     WriteSample(writer, black, false);
                     bitsRead += black;
                 }
             }
         }
         writer.FlushBuffer();
         return writer.BytesWritten();
     }
     catch (Exception /*ex*/)
     {
         //ex.GetType();
         return 0;
     }
 }
Example #2
0
 /// <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);
 }
Example #3
0
        /// <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)*/);
            }
        }
Example #4
0
 /// <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)));
 }
Example #5
0
 /// <summary>
 /// Counts the consecutive zero bits in an image line.
 /// </summary>
 /// <param name="reader">The reader.</param>
 /// <param name="bitsLeft">The bits left.</param>
 private static uint CountZeroBits(BitReader reader, uint bitsLeft)
 {
     uint found = 0;
     for (;;)
     {
         uint bits;
         int @byte = reader.PeekByte(out bits);
         uint hits = _zeroRuns[@byte];
         if (hits < bits)
         {
             if (hits > 0)
                 reader.SkipBits(hits);
             found += hits;
             return found >= bitsLeft ? bitsLeft : found;
         }
         found += bits;
         if (found >= bitsLeft)
             return bitsLeft;
         reader.NextByte();
     }
 }
Example #6
0
        /// <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)*/);
            }
        }
Example #7
0
 /// <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);
 }
Example #8
0
 /// <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)));
 }