Пример #1
0
 //0 xxxxxxx   // val 0 - 127                 //  8 bits
 //10 xxxxxxxx // val 128 - 383               // 10 bits
 //11 xxxxxxxx0 // val 384 - 639              // 11 bits
 //11 xxxxxxxx1 xxxx0 // val 384 - 4479       // 16 bits
 //11 xxxxxxxx1 xxxx1 xxxx0 // 384 - 65919    // 21 bits
 //11 xxxxxxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx1 xxxx0  // 81 bits worst case
 public static void WriteDynamicLength(BitStreamWriter aWriter, ulong aValue)
 {
     if (aValue < 128)
     {
         aWriter.WriteBit(0);
         aWriter.WriteBits(aValue, 7);
     }
     else if (aValue < 384)
     {
         aWriter.WriteBit(1);
         aWriter.WriteBit(0);
         aWriter.WriteBits(aValue - 128UL, 8);
     }
     else
     {
         aValue -= 384UL;
         aWriter.WriteBit(1);
         aWriter.WriteBit(1);
         aWriter.WriteBits(aValue, 8);
         aValue >>= 8;
         while (aValue > 0)
         {
             aWriter.WriteBit(1);
             aWriter.WriteBits(aValue, 4);
             aValue >>= 4;
         }
         aWriter.WriteBit(0);
     }
 }
Пример #2
0
        public static void ChangeDemoDir(SourceDemo demo, Stream s, string newDir)
        {
            void Write(byte[] buf) => s.Write(buf, 0, buf.Length);

            string old = demo.Header.GameDirectory;

            if (old == newDir)
            {
                // no difference
                Write(demo.Reader.Data);
                return;
            }
            int             lenDiff = newDir.Length - old.Length;
            BitStreamReader bsr     = demo.Reader;

            byte[] dirBytes = Encoding.ASCII.GetBytes(newDir);

            Write(bsr.ReadBytes(796));
            Write(dirBytes);             // header doesn't matter but I change it anyway
            Write(new byte[260 - newDir.Length]);
            bsr.SkipBytes(260);
            Write(bsr.ReadBytes(12));
            byte[] tmp = BitConverter.GetBytes((uint)(bsr.ReadUInt() + lenDiff));
            if (!BitConverter.IsLittleEndian)
            {
                tmp = tmp.Reverse().ToArray();
            }
            Write(tmp);

            foreach (SignOn signOn in demo.FilterForPacket <SignOn>().Where(signOn => signOn.FilterForMessage <SvcServerInfo>().Any()))
            {
                // catch up to signOn packet
                int byteCount = (signOn.Reader.AbsoluteBitIndex - bsr.AbsoluteBitIndex) / 8;
                Write(bsr.ReadBytes(byteCount));
                bsr.SkipBits(signOn.Reader.BitLength);

                BitStreamWriter bsw          = new BitStreamWriter();
                BitStreamReader signOnReader = signOn.Reader;
                bsw.WriteBits(signOnReader.ReadRemainingBits());
                signOnReader = signOnReader.FromBeginning();
                int bytesToMessageStreamSize = demo.DemoInfo.MaxSplitscreenPlayers * 76 + 8;
                signOnReader.SkipBytes(bytesToMessageStreamSize);
                // edit the message stream length - read uint, and edit at index before the reading of said uint
                bsw.EditIntAtIndex((int)(signOnReader.ReadUInt() + lenDiff), signOnReader.CurrentBitIndex - 32, 32);

                // actually change the game dir
                SvcServerInfo serverInfo = signOn.FilterForMessage <SvcServerInfo>().Single();
                int           editIndex  = serverInfo.GameDirBitIndex - signOn.Reader.AbsoluteBitIndex;
                bsw.RemoveBitsAtIndex(editIndex, old.Length * 8);
                bsw.InsertBitsAtIndex(dirBytes, editIndex, newDir.Length * 8);
                Write(bsw.AsArray);
            }
            Write(bsr.ReadRemainingBits().bytes);
        }
        // writes a edited version of the given demo to the stream
        // this is all manually hacked together and it shall stay this way for now
        public static void RemoveCaptions(SourceDemo demo, Stream s)
        {
            void Write(byte[] buf) => s.Write(buf, 0, buf.Length);

            Packet[] closeCaptionPackets = demo.FilterForPacket <Packet>()
                                           .Where(packet => packet.FilterForMessage <SvcUserMessage>()
                                                  .Any(frame => frame.MessageType == UserMessageType.CloseCaption)).ToArray();

            if (closeCaptionPackets.Length == 0)
            {
                Write(demo.Reader.Data);
                return;
            }

            int changedPackets = 0;

            Write(demo.Header.Reader.ReadRemainingBits().bytes);

            foreach (PacketFrame frame in demo.Frames)
            {
                if (frame.Packet != closeCaptionPackets[changedPackets])
                {
                    Write(frame.Reader.ReadRemainingBits().bytes);                     // write frames that aren't changed
                }
                else
                {
                    Packet          p    = (Packet)frame.Packet;
                    BitStreamWriter bsw  = new BitStreamWriter(frame.Reader.BitLength / 8);
                    var             last = p.MessageStream.Last().message;
                    int             len  = last.Reader.AbsoluteStart - frame.Reader.AbsoluteStart + last.Reader.BitLength;
                    bsw.WriteBits(frame.Reader.ReadBits(len), len);
                    int msgSizeOffset = p.MessageStream.Reader.AbsoluteStart - frame.Reader.AbsoluteStart;
                    int typeInfoLen   = demo.DemoInfo.NetMsgTypeBits + demo.DemoInfo.UserMessageLengthBits + 8;
                    bsw.RemoveBitsAtIndices(p.FilterForUserMessage <CloseCaption>()
                                            .Select(caption => (caption.Reader.AbsoluteStart - frame.Reader.AbsoluteStart - typeInfoLen,
                                                                caption.Reader.BitLength + typeInfoLen)));
                    bsw.WriteUntilByteBoundary();
                    bsw.EditIntAtIndex((bsw.BitLength - msgSizeOffset - 32) >> 3, msgSizeOffset, 32);
                    Write(bsw.AsArray);

                    // if we've edited all the packets, write the rest of the data in the demo
                    if (++changedPackets == closeCaptionPackets.Length)
                    {
                        BitStreamReader tmp = demo.Reader;
                        tmp.SkipBits(frame.Reader.AbsoluteStart + frame.Reader.BitLength);
                        Write(tmp.ReadRemainingBits().bytes);
                        break;
                    }
                }
            }
        }
Пример #4
0
        public void WriteBits()
        {
            var random = new Random(0);

            for (int i = 0; i < Iterations; i++)
            {
                int             skip = i % 16;
                BitStreamWriter bsw  = new BitStreamWriter();
                bsw.WriteBitsFromSInt(random.Next(), skip);
                int    bitLen = random.Next(1, 100);
                byte[] rand   = new byte[(bitLen >> 3) + ((bitLen & 0x07) == 0 ? 0 : 1)];
                random.NextBytes(rand);
                bsw.WriteBits(rand, bitLen);
                if ((bitLen & 0x07) != 0)
                {
                    rand[^ 1] &= (byte)(0xff >> (8 - (bitLen & 0x07)));                    // get rid of unused bits
Пример #5
0
        public static byte[] Encode(byte[] aData)
        {
            using (MemoryStream data = new MemoryStream())
            {
                BitStreamWriter writer = new BitStreamWriter(data);
                var             leaves = Analyze(aData);
                var             tree   = GenerateTree(leaves);
                tree.Serialize(writer);
                WriteDynamicLength(writer, (ulong)aData.LongLength);
                var lookup = GenerateLookup(leaves);

                for (int i = 0; i < aData.Length; i++)
                {
                    var n = lookup[aData[i]];
                    writer.WriteBits(n.bitPattern, n.bitCount);
                }
                writer.Flush();
                return(data.ToArray());
            }
        }
Пример #6
0
        public void SkipBits()
        {
            var             random = new Random(0);
            BitStreamWriter bsw    = new BitStreamWriter();
            List <(int skipCount, uint val)> data = new List <(int skipCount, uint val)>();

            byte[] randArr = new byte[100 / 8 + 1];
            random.NextBytes(randArr);
            for (int _ = 0; _ < Iterations; _++)
            {
                (int skip, uint val)r = (random.Next(0, 100), (uint)random.Next());
                data.Add(r);
                bsw.WriteBits(randArr, r.skip);
                bsw.WriteUInt(r.val);
            }
            BitStreamReader bsr = new BitStreamReader(bsw);

            for (int i = 0; i < Iterations; i++)
            {
                bsr.SkipBits(data[i].skipCount);
                Assert.AreEqual(data[i].val, bsr.ReadUInt(), $"index: {i}");
            }
        }
Пример #7
0
        /// <summary>
        /// Decodes a single pixel row.
        /// </summary>
        public byte[] DecodeRow(byte[] data)
        {
            m_Reset(CCITT4DecoderState.White);
            var reader = new BitStreamReaderReverse(new MemoryStream(data));
            var writer = new BitStreamWriter(new MemoryStream());

            while (reader.Position < reader.Length)
            {
                // read a bit
                m_CurrentValue = (m_CurrentValue << 1) | reader.ReadBit();
                m_CurrentBitLength++;
                if (m_CurrentBitLength > 13)
                {
                    throw new FormatException();
                }

                // did we get a EndOfLine code ?
                if ((m_CurrentBitLength == EOL[1]) && (m_CurrentValue == EOL[0]))
                {
                    m_Reset(0);
                    continue;
                }
                if (m_State == 0)
                {
                    // white makeup search
                    for (int i = 0; i < WhiteMakeUpCodes.GetLength(0); i++)
                    {
                        if ((WhiteMakeUpCodes[i, 1] == m_CurrentBitLength) &&
                            (WhiteMakeUpCodes[i, 0] == m_CurrentValue))
                        {
                            writer.WriteBits(WhiteMakeUpCodes[i, 2], true);
                            m_Reset(CCITT4DecoderState.WhiteTerminationRequired);
                            break;
                        }
                    }
                    if (m_State != 0)
                    {
                        continue;
                    }
                }
                if ((int)m_State <= 1)
                {
                    // white termination search
                    for (int i = 0; i < WhiteTerminatingCodes.GetLength(0); i++)
                    {
                        if ((WhiteTerminatingCodes[i, 1] == m_CurrentBitLength) &&
                            (WhiteTerminatingCodes[i, 0] == m_CurrentValue))
                        {
                            writer.WriteBits(i, true);
                            m_Reset(CCITT4DecoderState.Black);
                            break;
                        }
                    }
                    if ((int)m_State != 1)
                    {
                        continue;
                    }
                }
                if ((int)m_State == 2)
                {
                    // black makeup search
                    for (int i = 0; i < BlackMakeUpCodes.GetLength(0); i++)
                    {
                        if ((BlackMakeUpCodes[i, 1] == m_CurrentBitLength) &&
                            (BlackMakeUpCodes[i, 0] == m_CurrentValue))
                        {
                            writer.WriteBits(BlackMakeUpCodes[i, 2], false);
                            m_Reset(CCITT4DecoderState.BlackTerminationRequired);
                            break;
                        }
                    }
                    if ((int)m_State != 2)
                    {
                        continue;
                    }
                }
                if ((int)m_State >= 2)
                {
                    // black termination search
                    for (int i = 0; i < BlackTerminatingCodes.GetLength(0); i++)
                    {
                        if ((BlackTerminatingCodes[i, 1] == m_CurrentBitLength) &&
                            (BlackTerminatingCodes[i, 0] == m_CurrentValue))
                        {
                            writer.WriteBits(i, false);
                            m_Reset(CCITT4DecoderState.White);
                            break;
                        }
                    }
                    if ((int)m_State != 3)
                    {
                        continue;
                    }
                }
            }
            return(((MemoryStream)writer.BaseStream).ToArray());
        }
Пример #8
0
        /// <summary>
        /// Creates a 32x32 fingerprint for the specified bitmap.
        /// </summary>
        /// <param name="bitmap">The bitmap.</param>
        /// <returns>Returns a fingerprint with 6 bits per pixel (32 px = 6144 bit = 768 byte = 1024 base32 chars).</returns>
        public static FingerPrint Create(IBitmap32 bitmap)
        {
            using (Bitmap32 thumb = bitmap.Resize(32, 32, ResizeMode.TouchFromInside))
            {
                ARGBImageData data = thumb.Data;
                using (var ms = new MemoryStream())
                {
                    // calculate fingerprint and distance matrix
                    var     writer         = new BitStreamWriter(ms);
                    float[] distanceMatrix = new float[16];
                    {
                        int  x = 0, y = 0;
                        ARGB last = 0;
                        foreach (ARGB pixel in data.Data)
                        {
                            if (++x > 15)
                            {
                                x = 0;
                                ++y;
                            }

                            int r = pixel.Red >> 6;
                            int g = pixel.Green >> 6;
                            int b = pixel.Blue >> 6;
                            writer.WriteBits(r, 2);
                            writer.WriteBits(g, 2);
                            writer.WriteBits(b, 2);

                            unchecked
                            {
                                int   i        = ((y << 1) & 0xC) + (x >> 2);
                                float distance = Math.Abs(pixel.GetDistance(last));
                                distanceMatrix[i] += distance;
                                last = pixel;
                            }
                        }
                    }

                    // normalize matrix
                    float maxDistance = distanceMatrix.Max();
                    for (int i = 0; i < distanceMatrix.Length; i++)
                    {
                        distanceMatrix[i] /= maxDistance;
                    }

                    // calculate blocks
                    uint[] blocks = new uint[4];
                    int[]  index  = new int[] { 0, 2, 8, 10 };
                    for (int i = 0; i < 4; i++)
                    {
                        int  idx        = index[i];
                        uint blockValue = (uint)(255 * distanceMatrix[idx]) << 24;
                        blockValue |= (uint)(255 * distanceMatrix[idx + 1]) << 16;
                        blockValue |= (uint)(255 * distanceMatrix[idx + 4]) << 8;
                        blockValue |= (uint)(255 * distanceMatrix[idx + 5]);
                        blocks[i]   = blockValue;
                    }

                    /*
                     * uint b1 = (uint)(uint.MaxValue * (distanceMatrix[0] + distanceMatrix[1]  + distanceMatrix[4] + distanceMatrix[5]) /4);
                     * uint b2 = (uint)(uint.MaxValue * (distanceMatrix[3] + distanceMatrix[2]  + distanceMatrix[7] + distanceMatrix[6]) / 4);
                     * uint b3 = (uint)(uint.MaxValue * (distanceMatrix[12] + distanceMatrix[13]  + distanceMatrix[8]  + distanceMatrix[9]) / 4);
                     * uint b4 = (uint)(uint.MaxValue * (distanceMatrix[15] + distanceMatrix[14]  + distanceMatrix[11] + distanceMatrix[10]) / 4);
                     */
                    return(new FingerPrint(32, blocks, ms.ToArray()));
                }
            }
        }
Пример #9
0
 public static void WriteByte(this BitStreamWriter writer, Byte value)
 {
     writer.WriteBits(value, 8);
 }
Пример #10
0
 public static void WriteFloat32(this BitStreamWriter writer, Single value)
 {
     writer.WriteBits(BitConverterX.Float32ToUInt32(value), 32);
 }
Пример #11
0
 public static void WriteUInt32(this BitStreamWriter writer, UInt32 value)
 {
     writer.WriteBits(value, 32);
 }
Пример #12
0
 public static void WriteUInt16(this BitStreamWriter writer, UInt16 value)
 {
     writer.WriteBits(value, 16);
 }
Пример #13
0
 public static void WriteInt32(this BitStreamWriter writer, Int32 value)
 {
     writer.WriteBits(BitConverterX.Int32ToUInt32(value), 32);
 }
Пример #14
0
 public static void WriteChar(this BitStreamWriter writer, Char value)
 {
     writer.WriteBits(value, 16);
 }
Пример #15
0
 public void Serialize(BitStreamWriter aWriter)
 {
     aWriter.WriteBit(1);
     aWriter.WriteBits(data, 8);
 }