public void BitConverter() { /* * Unsigned, BE, 12bit "A B C" -> 0x0ABC -> 2748 * Signed , BE, 12bit "A B C" -> 0xFABC -> -1348 * Unsigned, LE, 12bit "B C A" -> 0x0ABC -> 2748 * Signed , LE, 12bit "B C A" -> 0xFABC -> -1348 */ byte[] val = null; val = BitWriter <BigEndian> .GetBytes(0xABC, 0); Assert.AreEqual(new byte[] { }, val); Assert.AreEqual(0, BigBitWriter.GetUInt64(val, 0)); Assert.AreEqual(0, BigBitWriter.GetInt64(val, 0)); val = BitWriter <BigEndian> .GetBytes(0xABC, 12); Assert.AreEqual(new byte[] { 0xab, 0xc0 }, val); Assert.AreEqual(2748, BigBitWriter.GetUInt64(val, 12)); Assert.AreEqual(-1348, BigBitWriter.GetInt64(val, 12)); val = BitWriter <LittleEndian> .GetBytes(0xABC, 0); Assert.AreEqual(new byte[] { }, val); Assert.AreEqual(0, LittleBitWriter.GetUInt64(val, 0)); Assert.AreEqual(0, LittleBitWriter.GetInt64(val, 0)); val = BitWriter <LittleEndian> .GetBytes(0xABC, 12); Assert.AreEqual(new byte[] { 0xbc, 0xa0 }, val); Assert.AreEqual(2748, LittleBitWriter.GetUInt64(val, 12)); Assert.AreEqual(-1348, LittleBitWriter.GetInt64(val, 12)); ulong bits = 0; bits = BitWriter <BigEndian> .GetBits(0xABC, 12); Assert.AreEqual(0xABC, bits); Assert.AreEqual(2748, BigBitWriter.GetUInt64(bits, 12)); Assert.AreEqual(-1348, BigBitWriter.GetInt64(bits, 12)); bits = BitWriter <LittleEndian> .GetBits(0xABC, 12); Assert.AreEqual(0xBCA, bits); Assert.AreEqual(2748, LittleBitWriter.GetUInt64(bits, 12)); Assert.AreEqual(-1348, LittleBitWriter.GetInt64(bits, 12)); }
public byte[] Encode(string text) { var len = text.Length * 7 + 24; var writer = new BitWriter(len); writer.WriteByte(2); writer.WriteInt(text.Length, 16); for (int i = 0; i < text.Length; i++) { var b = Convert.ToByte(text[i]); writer.WriteByte(b, 7); } return(writer.GetBytes()); }
public byte[] Encode(string text) { text = text.ToUpper(); var len = text.Length * 6 + 24; var writer = new BitWriter(len); writer.WriteByte(2); writer.WriteInt(text.Length, 16); for (int i = 0; i < text.Length; i++) { var index = GetChar6Index(text[i]); writer.WriteInt(index, 6); } return(writer.GetBytes()); }
public void GetBytes_Works_When_MoreThan64Bits() { /* There are 12 entries, * and we will Write them together in groups of 4. * In total, 96 bits, forcing the Writer to make 2 BinaryNumber * The bytes from GetBytes should match perfectly with these */ byte[] input = new byte[] { 12, 0, 157, 212, 255, 2, 42, 128, 188, 200, 10, 32 }; BitWriter writer = new BitWriter(); for (int i = 0; i < input.Length; i += 4) { writer.Write(BitConverter.ToUInt32(input, i)); } Assert.AreEqual(input, writer.GetBytes()); }
/// <summary> /// Compresses and writes booleans to writer /// </summary> /// <param name="w"></param> /// <param name="values"></param> private void CompressBooleanTrack(BinaryWriter w, IList <object> values) { // Compressed Header w.Write((short)0x04); w.Write((short)0); w.Write((short)0x20); // default values offset w.Write((short)1); // bits per entry w.Write(0x21); // compressed data start w.Write(values.Count); // frame count w.Write(0); // all 0s for booleans w.Write(0); w.Write(0); w.Write(0); BitWriter bitWriter = new BitWriter(); foreach (bool b in values) { bitWriter.WriteBits(b ? 1 : 0, 1); } w.Write(bitWriter.GetBytes()); }
public byte[] GetBytes() { return(_writer.GetBytes()); }
/// <summary> /// Compresses <see cref="AnimTrackTransform" track and writes to writer/> /// </summary> /// <param name="w"></param> /// <param name="values"></param> private void CompressTransformTracks(BinaryWriter w, IList <object> values) { Quantanizer SX = new Quantanizer(); Quantanizer SY = new Quantanizer(); Quantanizer SZ = new Quantanizer(); Quantanizer RX = new Quantanizer(); Quantanizer RY = new Quantanizer(); Quantanizer RZ = new Quantanizer(); Quantanizer X = new Quantanizer(); Quantanizer Y = new Quantanizer(); Quantanizer Z = new Quantanizer(); // pre-process foreach (AnimTrackTransform transform in values) { SX.Add(transform.SX); SY.Add(transform.SY); SZ.Add(transform.SZ); RX.Add(transform.RX); RY.Add(transform.RY); RZ.Add(transform.RZ); X.Add(transform.X); Y.Add(transform.Y); Z.Add(transform.Z); } short Flags = 0; ushort BitsPerEntry = 0; bool hasScale = (!SX.Constant || !SY.Constant || !SZ.Constant); bool hasRotation = (!RX.Constant || !RY.Constant || !RZ.Constant); bool hasPosition = (!X.Constant || !Y.Constant || !Z.Constant); if (!hasScale) { Flags |= 0x02; } else { BitsPerEntry += (ushort)((SX.Constant ? 0 : SX.GetBitCount(Epsilon)) + (SY.Constant ? 0 : SY.GetBitCount(Epsilon)) + (SZ.Constant ? 0 : SZ.GetBitCount(Epsilon))); Flags |= 0x01; } if (hasRotation) { BitsPerEntry += (ushort)((RX.Constant ? 0 : RX.GetBitCount(Epsilon)) + (RY.Constant ? 0 : RY.GetBitCount(Epsilon)) + (RZ.Constant ? 0 : RZ.GetBitCount(Epsilon)) + 1); // the 1 is for extra w rotation bit Flags |= 0x04; } if (hasPosition) { BitsPerEntry += (ushort)((X.Constant ? 0 : X.GetBitCount(Epsilon)) + (Y.Constant ? 0 : Y.GetBitCount(Epsilon)) + (Z.Constant ? 0 : Z.GetBitCount(Epsilon))); Flags |= 0x08; } // Compressed Header w.Write((short)0x04); w.Write(Flags); w.Write((short)(0x10 + 0x10 * 9)); // default values offset w.Write(BitsPerEntry); w.Write(0x10 + 0x10 * 9 + sizeof(float) * 11); // compressed data start w.Write(values.Count); // frame count // write chunks w.Write(SX.Min); w.Write(SX.Max); w.Write((long)SX.GetBitCount(Epsilon)); w.Write(SY.Min); w.Write(SY.Max); w.Write((long)SY.GetBitCount(Epsilon)); w.Write(SZ.Min); w.Write(SZ.Max); w.Write((long)SZ.GetBitCount(Epsilon)); w.Write(RX.Min); w.Write(RX.Max); w.Write((long)RX.GetBitCount(Epsilon)); w.Write(RY.Min); w.Write(RY.Max); w.Write((long)RY.GetBitCount(Epsilon)); w.Write(RZ.Min); w.Write(RZ.Max); w.Write((long)RZ.GetBitCount(Epsilon)); w.Write(X.Min); w.Write(X.Max); w.Write((long)X.GetBitCount(Epsilon)); w.Write(Y.Min); w.Write(Y.Max); w.Write((long)Y.GetBitCount(Epsilon)); w.Write(Z.Min); w.Write(Z.Max); w.Write((long)Z.GetBitCount(Epsilon)); // write default values AnimTrackTransform defaultValue = (AnimTrackTransform)values[0]; w.Write(defaultValue.SX); w.Write(defaultValue.SY); w.Write(defaultValue.SZ); w.Write(defaultValue.RX); w.Write(defaultValue.RY); w.Write(defaultValue.RZ); w.Write(defaultValue.RW); w.Write(defaultValue.X); w.Write(defaultValue.Y); w.Write(defaultValue.Z); w.Write(0); // write compressed values BitWriter writer = new BitWriter(); foreach (AnimTrackTransform transform in values) { if (hasScale) { writer.WriteBits(SX.GetQuantanizedValue(transform.SX), SX.GetBitCount(Epsilon)); writer.WriteBits(SY.GetQuantanizedValue(transform.SY), SY.GetBitCount(Epsilon)); writer.WriteBits(SZ.GetQuantanizedValue(transform.SZ), SZ.GetBitCount(Epsilon)); } if (hasRotation) { writer.WriteBits(RX.GetQuantanizedValue(transform.RX), RX.GetBitCount(Epsilon)); writer.WriteBits(RY.GetQuantanizedValue(transform.RY), RY.GetBitCount(Epsilon)); writer.WriteBits(RZ.GetQuantanizedValue(transform.RZ), RZ.GetBitCount(Epsilon)); } if (hasPosition) { writer.WriteBits(X.GetQuantanizedValue(transform.X), X.GetBitCount(Epsilon)); writer.WriteBits(Y.GetQuantanizedValue(transform.Y), Y.GetBitCount(Epsilon)); writer.WriteBits(Z.GetQuantanizedValue(transform.Z), Z.GetBitCount(Epsilon)); } if (hasRotation) { // flip w bit float calculateW = (float)Math.Sqrt(Math.Abs(1 - ( RX.DecompressedValue(transform.RX) * RX.DecompressedValue(transform.RX) + RY.DecompressedValue(transform.RY) * RY.DecompressedValue(transform.RY) + RZ.DecompressedValue(transform.RZ) * RZ.DecompressedValue(transform.RZ)))); writer.WriteBits(Math.Sign((int)transform.RW) != Math.Sign((int)calculateW) ? 1 : 0, 1); } } w.Write(writer.GetBytes()); }
/// <summary> /// Compresses <see cref="AnimTrackTransform"></see> track and writes to writer /// </summary> /// <param name="w"></param> /// <param name="values"></param> private void CompressTransformTracks(BinaryWriter w, IList <object> values) { Quantanizer sx = new Quantanizer(); Quantanizer sy = new Quantanizer(); Quantanizer sz = new Quantanizer(); Quantanizer rx = new Quantanizer(); Quantanizer ry = new Quantanizer(); Quantanizer rz = new Quantanizer(); Quantanizer x = new Quantanizer(); Quantanizer y = new Quantanizer(); Quantanizer z = new Quantanizer(); // pre-process foreach (AnimTrackTransform transform in values) { sx.Add(transform.Sx); sy.Add(transform.Sy); sz.Add(transform.Sz); rx.Add(transform.Rx); ry.Add(transform.Ry); rz.Add(transform.Rz); x.Add(transform.X); y.Add(transform.Y); z.Add(transform.Z); } short flags = 0; ushort bitsPerEntry = 0; bool hasScale = (!sx.Constant || !sy.Constant || !sz.Constant); bool hasRotation = (!rx.Constant || !ry.Constant || !rz.Constant); bool hasPosition = (!x.Constant || !y.Constant || !z.Constant); if (sx.GetBitCount(epsilon) == -1 || sy.GetBitCount(epsilon) == -1 || (sz.GetBitCount(epsilon) == -1 || rx.GetBitCount(epsilon) == -1) || (ry.GetBitCount(epsilon) == -1 || rz.GetBitCount(epsilon) == -1 || (x.GetBitCount(epsilon) == -1 || y.GetBitCount(epsilon) == -1)) || z.GetBitCount(epsilon) == -1) { throw new Exception("Compression Level is too small to compress!"); } if (!hasScale) { flags |= 0x02; } else { bitsPerEntry += (ushort)((sx.Constant ? 0 : sx.GetBitCount(epsilon)) + (sy.Constant ? 0 : sy.GetBitCount(epsilon)) + (sz.Constant ? 0 : sz.GetBitCount(epsilon))); flags |= 0x01; } if (hasRotation) { bitsPerEntry += (ushort)((rx.Constant ? 0 : rx.GetBitCount(epsilon)) + (ry.Constant ? 0 : ry.GetBitCount(epsilon)) + (rz.Constant ? 0 : rz.GetBitCount(epsilon)) + 1); // the 1 is for extra w rotation bit flags |= 0x04; } if (hasPosition) { bitsPerEntry += (ushort)((x.Constant ? 0 : x.GetBitCount(epsilon)) + (y.Constant ? 0 : y.GetBitCount(epsilon)) + (z.Constant ? 0 : z.GetBitCount(epsilon))); flags |= 0x08; } // Compressed Header w.Write((short)0x04); w.Write(flags); w.Write((short)160); w.Write(bitsPerEntry); w.Write(204); w.Write(values.Count); w.Write(sx.Min); w.Write(sx.Max); w.Write(hasScale ? sx.GetBitCount(epsilon) : 16L); w.Write(sy.Min); w.Write(sy.Max); w.Write(hasScale ? sy.GetBitCount(epsilon) : 16L); w.Write(sz.Min); w.Write(sz.Max); w.Write(hasScale ? sz.GetBitCount(epsilon) : 16L); w.Write(rx.Min); w.Write(rx.Max); w.Write(hasRotation ? rx.GetBitCount(epsilon) : 16L); w.Write(ry.Min); w.Write(ry.Max); w.Write(hasRotation ? ry.GetBitCount(epsilon) : 16L); w.Write(rz.Min); w.Write(rz.Max); w.Write(hasRotation ? rz.GetBitCount(epsilon) : 16L); w.Write(x.Min); w.Write(x.Max); w.Write(hasPosition ? x.GetBitCount(epsilon) : 16L); w.Write(y.Min); w.Write(y.Max); w.Write(hasPosition ? y.GetBitCount(epsilon) : 16L); w.Write(z.Min); w.Write(z.Max); w.Write(hasPosition ? z.GetBitCount(epsilon) : 16L); AnimTrackTransform defaultValue = (AnimTrackTransform)values[0]; w.Write(defaultValue.Sx); w.Write(defaultValue.Sy); w.Write(defaultValue.Sz); w.Write(defaultValue.Rx); w.Write(defaultValue.Ry); w.Write(defaultValue.Rz); w.Write(defaultValue.Rw); w.Write(defaultValue.X); w.Write(defaultValue.Y); w.Write(defaultValue.Z); w.Write(0); // write compressed values BitWriter writer = new BitWriter(); foreach (AnimTrackTransform transform in values) { if (hasScale) { writer.WriteBits(sx.GetQuantanizedValue(transform.Sx), sx.GetBitCount(epsilon)); writer.WriteBits(sy.GetQuantanizedValue(transform.Sy), sy.GetBitCount(epsilon)); writer.WriteBits(sz.GetQuantanizedValue(transform.Sz), sz.GetBitCount(epsilon)); } if (hasRotation) { writer.WriteBits(rx.GetQuantanizedValue(transform.Rx), rx.GetBitCount(epsilon)); writer.WriteBits(ry.GetQuantanizedValue(transform.Ry), ry.GetBitCount(epsilon)); writer.WriteBits(rz.GetQuantanizedValue(transform.Rz), rz.GetBitCount(epsilon)); } if (hasPosition) { writer.WriteBits(x.GetQuantanizedValue(transform.X), x.GetBitCount(epsilon)); writer.WriteBits(y.GetQuantanizedValue(transform.Y), y.GetBitCount(epsilon)); writer.WriteBits(z.GetQuantanizedValue(transform.Z), z.GetBitCount(epsilon)); } if (hasRotation) { // flip w bit float calculateW = (float)Math.Sqrt(Math.Abs(1 - ( rx.DecompressedValue(transform.Rx) * rx.DecompressedValue(transform.Rx) + ry.DecompressedValue(transform.Ry) * ry.DecompressedValue(transform.Ry) + rz.DecompressedValue(transform.Rz) * rz.DecompressedValue(transform.Rz)))); writer.WriteBits(Math.Sign(transform.Rw) != Math.Sign(calculateW) ? 1 : 0, 1); } } w.Write(writer.GetBytes()); }
/// <summary> /// Compresses <see cref="AnimTrackTransform"></see> track and writes to writer /// </summary> /// <param name="w"></param> /// <param name="values"></param> private void CompressTransformTracks(BinaryWriter w, IList <object> values) { Quantanizer sx = new Quantanizer(); Quantanizer sy = new Quantanizer(); Quantanizer sz = new Quantanizer(); Quantanizer rx = new Quantanizer(); Quantanizer ry = new Quantanizer(); Quantanizer rz = new Quantanizer(); Quantanizer x = new Quantanizer(); Quantanizer y = new Quantanizer(); Quantanizer z = new Quantanizer(); // pre-process foreach (AnimTrackTransform transform in values) { sx.Add(transform.Sx); sy.Add(transform.Sy); sz.Add(transform.Sz); rx.Add(transform.Rx); ry.Add(transform.Ry); rz.Add(transform.Rz); x.Add(transform.X); y.Add(transform.Y); z.Add(transform.Z); } short flags = 0; ushort bitsPerEntry = 0; bool hasScale = (!sx.Constant || !sy.Constant || !sz.Constant); bool hasRotation = (!rx.Constant || !ry.Constant || !rz.Constant); bool hasPosition = (!x.Constant || !y.Constant || !z.Constant); if (!hasScale) { flags |= 0x02; } else { bitsPerEntry += (ushort)((sx.Constant ? 0 : sx.GetBitCount(epsilon)) + (sy.Constant ? 0 : sy.GetBitCount(epsilon)) + (sz.Constant ? 0 : sz.GetBitCount(epsilon))); flags |= 0x01; } if (hasRotation) { bitsPerEntry += (ushort)((rx.Constant ? 0 : rx.GetBitCount(epsilon)) + (ry.Constant ? 0 : ry.GetBitCount(epsilon)) + (rz.Constant ? 0 : rz.GetBitCount(epsilon)) + 1); // the 1 is for extra w rotation bit flags |= 0x04; } if (hasPosition) { bitsPerEntry += (ushort)((x.Constant ? 0 : x.GetBitCount(epsilon)) + (y.Constant ? 0 : y.GetBitCount(epsilon)) + (z.Constant ? 0 : z.GetBitCount(epsilon))); flags |= 0x08; } // Compressed Header w.Write((short)0x04); w.Write(flags); w.Write((short)(0x10 + 0x10 * 9)); // default values offset w.Write(bitsPerEntry); w.Write(0x10 + 0x10 * 9 + sizeof(float) * 11); // compressed data start w.Write(values.Count); // frame count // write chunks w.Write(sx.Min); w.Write(sx.Max); w.Write((long)sx.GetBitCount(epsilon)); w.Write(sy.Min); w.Write(sy.Max); w.Write((long)sy.GetBitCount(epsilon)); w.Write(sz.Min); w.Write(sz.Max); w.Write((long)sz.GetBitCount(epsilon)); w.Write(rx.Min); w.Write(rx.Max); w.Write((long)rx.GetBitCount(epsilon)); w.Write(ry.Min); w.Write(ry.Max); w.Write((long)ry.GetBitCount(epsilon)); w.Write(rz.Min); w.Write(rz.Max); w.Write((long)rz.GetBitCount(epsilon)); w.Write(x.Min); w.Write(x.Max); w.Write((long)x.GetBitCount(epsilon)); w.Write(y.Min); w.Write(y.Max); w.Write((long)y.GetBitCount(epsilon)); w.Write(z.Min); w.Write(z.Max); w.Write((long)z.GetBitCount(epsilon)); // write default values AnimTrackTransform defaultValue = (AnimTrackTransform)values[0]; w.Write(defaultValue.Sx); w.Write(defaultValue.Sy); w.Write(defaultValue.Sz); w.Write(defaultValue.Rx); w.Write(defaultValue.Ry); w.Write(defaultValue.Rz); w.Write(defaultValue.Rw); w.Write(defaultValue.X); w.Write(defaultValue.Y); w.Write(defaultValue.Z); w.Write(0); // write compressed values BitWriter writer = new BitWriter(); foreach (AnimTrackTransform transform in values) { if (hasScale) { writer.WriteBits(sx.GetQuantanizedValue(transform.Sx), sx.GetBitCount(epsilon)); writer.WriteBits(sy.GetQuantanizedValue(transform.Sy), sy.GetBitCount(epsilon)); writer.WriteBits(sz.GetQuantanizedValue(transform.Sz), sz.GetBitCount(epsilon)); } if (hasRotation) { writer.WriteBits(rx.GetQuantanizedValue(transform.Rx), rx.GetBitCount(epsilon)); writer.WriteBits(ry.GetQuantanizedValue(transform.Ry), ry.GetBitCount(epsilon)); writer.WriteBits(rz.GetQuantanizedValue(transform.Rz), rz.GetBitCount(epsilon)); } if (hasPosition) { writer.WriteBits(x.GetQuantanizedValue(transform.X), x.GetBitCount(epsilon)); writer.WriteBits(y.GetQuantanizedValue(transform.Y), y.GetBitCount(epsilon)); writer.WriteBits(z.GetQuantanizedValue(transform.Z), z.GetBitCount(epsilon)); } if (hasRotation) { // flip w bit float calculateW = (float)Math.Sqrt(Math.Abs(1 - ( rx.DecompressedValue(transform.Rx) * rx.DecompressedValue(transform.Rx) + ry.DecompressedValue(transform.Ry) * ry.DecompressedValue(transform.Ry) + rz.DecompressedValue(transform.Rz) * rz.DecompressedValue(transform.Rz)))); writer.WriteBits(Math.Sign((int)transform.Rw) != Math.Sign((int)calculateW) ? 1 : 0, 1); } } w.Write(writer.GetBytes()); }