Ejemplo n.º 1
0
        /// <summary>
        /// Writes the image data.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="count">The count of bits (pels) to encode.</param>
        /// <param name="white">The color of the pels.</param>
        private static void WriteSample(BitWriter writer, uint count, bool white)
        {
            uint[] terminatingCodes = white ? WhiteTerminatingCodes : BlackTerminatingCodes;
            uint[] makeUpCodes = white ? WhiteMakeUpCodes : BlackMakeUpCodes;

            // The make-up code for 2560 will be written as often as required:
            while (count >= 2624)
            {
                writer.WriteTableLine(makeUpCodes, 39); // Magic: 2560
                count -= 2560;
            }
            // A make-up code for a multiple of 64 will be written if required:
            if (count > 63)
            {
                uint line = count / 64 - 1;
                writer.WriteTableLine(makeUpCodes, line);
                count -= (line + 1) * 64;
            }
            // And finally the terminating code for the remaining value (0 through 63):
            writer.WriteTableLine(terminatingCodes, count);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Encodes a bitonal bitmap using 2D group 4 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>
 internal static int DoFaxEncodingGroup4(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)
         {
             FaxEncode2DRow(writer, bytesFileOffset, imageBits, y, (y != 0) ? y - 1 : 0xffffffff, width, height, bytesPerLineBmp);
         }
         writer.FlushBuffer();
         return writer.BytesWritten();
     }
     catch (Exception ex)
     {
         ex.GetType();
         return 0;
     }
 }
Ejemplo n.º 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)*/);
            }
        }
Ejemplo n.º 4
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;
     }
 }
        /// <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)*/);
            }
        }