public void InsertTest_IndexInMiddle_InsertionOnIndex() { BitList bl = new BitList(8); bl.InsertAt(3, true); Assert.AreEqual(true, bl[3]); }
public void AddTest_IfAddIntVal_AddsBit() { BitList bl = new BitList(8); bl.Add(1); Assert.AreEqual(true, bl[8]); }
public BitList SubList(int startindex, int endindex) { int length = endindex - startindex; if (length <= 0) { throw new IndexOutOfRangeException(); } BitList b = new BitList(length); for (int i = startindex; i < endindex + 1; i++) { b.Add(this[i]); } return b; }
public void CheckedAdd_AddedEigthTrueInARow_AddsEightZeroes() { const int numberOfStartElements = 5; BitList bl = new BitList(numberOfStartElements); for (int i = 0; i < 8; i++) { bl.CheckedAdd(1); } Assert.AreEqual(16 + numberOfStartElements, bl.Count); for (int i = 8 + numberOfStartElements; i < 16 + numberOfStartElements; i++) { Assert.False(bl[i]); } }
public void Flush_Test() { PrivateType pt = new PrivateType(typeof(JpegImage)); BitList bl = new BitList(); bl.Add(true); bl.Add(true); bl.Add(false); byte[] output = (byte[]) pt.InvokeStatic("_flush", bl); byte[] expected = new byte[1] {192}; // 11000000 Assert.AreEqual(expected, output); }
public void UShortToBits_Test() { BitList bitList = new BitList(); ushort input = 3; byte inputLen = 2; PrivateType pt = new PrivateType(typeof(JpegImage)); pt.InvokeStatic("_ushortToBits", new object[] {bitList, input, inputLen}); BitList expectedBitList = new BitList(); expectedBitList.Add(true); expectedBitList.Add(true); Assert.AreEqual(expectedBitList, bitList); }
public void HuffmanEncode() //TODO: Delete this { JpegImage ji = new JpegImage(new Bitmap(200, 100), 100, 4); PrivateObject po = new PrivateObject(ji); BitList bl = new BitList(); short[,] inputBlock = new short[8, 8] { {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, }; HuffmanTable inputHuffDC = new HuffmanTable( #region HuffmanElements new HuffmanElement(0x00, 0x00, 2), new HuffmanElement(0x01, 0x02, 3), new HuffmanElement(0x02, 0x03, 3), new HuffmanElement(0x03, 0x04, 3), new HuffmanElement(0x04, 0x05, 3), new HuffmanElement(0x05, 0x06, 3), new HuffmanElement(0x06, 0x0e, 4), new HuffmanElement(0x07, 0x1e, 5), new HuffmanElement(0x08, 0x3e, 6), new HuffmanElement(0x09, 0x7e, 7), new HuffmanElement(0x0a, 0xfe, 8), new HuffmanElement(0x0b, 0x1fe, 9) #endregion ); HuffmanTable inputHuffAC = new HuffmanTable( #region HuffmanElements new HuffmanElement(0x00, 0xa, 4), new HuffmanElement(0x01, 0x0, 2), new HuffmanElement(0x02, 0x1, 2), new HuffmanElement(0x03, 0x4, 3), new HuffmanElement(0x04, 0xb, 4), new HuffmanElement(0x05, 0x1a, 5), new HuffmanElement(0x06, 0x78, 7), new HuffmanElement(0x07, 0xf8, 8), new HuffmanElement(0x08, 0x3f6, 10), new HuffmanElement(0x09, 0xff82, 16), new HuffmanElement(0x0a, 0xff83, 16), new HuffmanElement(0x11, 0xc, 4), new HuffmanElement(0x12, 0x1b, 5), new HuffmanElement(0x13, 0x79, 7), new HuffmanElement(0x14, 0x1f6, 9), new HuffmanElement(0x15, 0x7f6, 11), new HuffmanElement(0x16, 0xff84, 16), new HuffmanElement(0x17, 0xff85, 16), new HuffmanElement(0x18, 0xff86, 16), new HuffmanElement(0x19, 0xff87, 16), new HuffmanElement(0x1a, 0xff88, 16), new HuffmanElement(0x21, 0x1c, 5), new HuffmanElement(0x22, 0xf9, 8), new HuffmanElement(0x23, 0x3f7, 10), new HuffmanElement(0x24, 0xff4, 12), new HuffmanElement(0x25, 0xff89, 16), new HuffmanElement(0x26, 0xff8a, 16), new HuffmanElement(0x27, 0xff8b, 16), new HuffmanElement(0x28, 0xff8c, 16), new HuffmanElement(0x29, 0xff8d, 16), new HuffmanElement(0x2a, 0xff8e, 16), new HuffmanElement(0x31, 0x3a, 6), new HuffmanElement(0x32, 0x1f7, 9), new HuffmanElement(0x33, 0xff5, 12), new HuffmanElement(0x34, 0xff8f, 16), new HuffmanElement(0x35, 0xff90, 16), new HuffmanElement(0x36, 0xff91, 16), new HuffmanElement(0x37, 0xff92, 16), new HuffmanElement(0x38, 0xff93, 16), new HuffmanElement(0x39, 0xff94, 16), new HuffmanElement(0x3a, 0xff95, 16), new HuffmanElement(0x41, 0x3b, 6), new HuffmanElement(0x42, 0x3f8, 10), new HuffmanElement(0x43, 0xff96, 16), new HuffmanElement(0x44, 0xff97, 16), new HuffmanElement(0x45, 0xff98, 16), new HuffmanElement(0x46, 0xff99, 16), new HuffmanElement(0x47, 0xff9a, 16), new HuffmanElement(0x48, 0xff9b, 16), new HuffmanElement(0x49, 0xff9c, 16), new HuffmanElement(0x4a, 0xff9d, 16), new HuffmanElement(0x51, 0x7a, 7), new HuffmanElement(0x52, 0x7f7, 11), new HuffmanElement(0x53, 0xff9e, 16), new HuffmanElement(0x54, 0xff9f, 16), new HuffmanElement(0x55, 0xffa0, 16), new HuffmanElement(0x56, 0xffa1, 16), new HuffmanElement(0x57, 0xffa2, 16), new HuffmanElement(0x58, 0xffa3, 16), new HuffmanElement(0x59, 0xffa4, 16), new HuffmanElement(0x5a, 0xffa5, 16), new HuffmanElement(0x61, 0x7b, 7), new HuffmanElement(0x62, 0xff6, 12), new HuffmanElement(0x63, 0xffa6, 16), new HuffmanElement(0x64, 0xffa7, 16), new HuffmanElement(0x65, 0xffa8, 16), new HuffmanElement(0x66, 0xffa9, 16), new HuffmanElement(0x67, 0xffaa, 16), new HuffmanElement(0x68, 0xffab, 16), new HuffmanElement(0x69, 0xffac, 16), new HuffmanElement(0x6a, 0xffad, 16), new HuffmanElement(0x71, 0xfa, 8), new HuffmanElement(0x72, 0xff7, 12), new HuffmanElement(0x73, 0xffae, 16), new HuffmanElement(0x74, 0xffaf, 16), new HuffmanElement(0x75, 0xffb0, 16), new HuffmanElement(0x76, 0xffb1, 16), new HuffmanElement(0x77, 0xffb2, 16), new HuffmanElement(0x78, 0xffb3, 16), new HuffmanElement(0x79, 0xffb4, 16), new HuffmanElement(0x7a, 0xffb5, 16), new HuffmanElement(0x81, 0x1f8, 9), new HuffmanElement(0x82, 0x7fc0, 15), new HuffmanElement(0x83, 0xffb6, 16), new HuffmanElement(0x84, 0xffb7, 16), new HuffmanElement(0x85, 0xffb8, 16), new HuffmanElement(0x86, 0xffb9, 16), new HuffmanElement(0x87, 0xffba, 16), new HuffmanElement(0x88, 0xffbb, 16), new HuffmanElement(0x89, 0xffbc, 16), new HuffmanElement(0x8a, 0xffbd, 16), new HuffmanElement(0x91, 0x1f9, 9), new HuffmanElement(0x92, 0xffbe, 16), new HuffmanElement(0x93, 0xffbf, 16), new HuffmanElement(0x94, 0xffc0, 16), new HuffmanElement(0x95, 0xffc1, 16), new HuffmanElement(0x96, 0xffc2, 16), new HuffmanElement(0x97, 0xffc3, 16), new HuffmanElement(0x98, 0xffc4, 16), new HuffmanElement(0x99, 0xffc5, 16), new HuffmanElement(0x9a, 0xffc6, 16), new HuffmanElement(0xa1, 0x1fa, 9), new HuffmanElement(0xa2, 0xffc7, 16), new HuffmanElement(0xa3, 0xffc8, 16), new HuffmanElement(0xa4, 0xffc9, 16), new HuffmanElement(0xa5, 0xffca, 16), new HuffmanElement(0xa6, 0xffcb, 16), new HuffmanElement(0xa7, 0xffcc, 16), new HuffmanElement(0xa8, 0xffcd, 16), new HuffmanElement(0xa9, 0xffce, 16), new HuffmanElement(0xaa, 0xffcf, 16), new HuffmanElement(0xb1, 0x3f9, 10), new HuffmanElement(0xb2, 0xffd0, 16), new HuffmanElement(0xb3, 0xffd1, 16), new HuffmanElement(0xb4, 0xffd2, 16), new HuffmanElement(0xb5, 0xffd3, 16), new HuffmanElement(0xb6, 0xffd4, 16), new HuffmanElement(0xb7, 0xffd5, 16), new HuffmanElement(0xb8, 0xffd6, 16), new HuffmanElement(0xb9, 0xffd7, 16), new HuffmanElement(0xba, 0xffd8, 16), new HuffmanElement(0xc1, 0x3fa, 10), new HuffmanElement(0xc2, 0xffd9, 16), new HuffmanElement(0xc3, 0xffda, 16), new HuffmanElement(0xc4, 0xffdb, 16), new HuffmanElement(0xc5, 0xffdc, 16), new HuffmanElement(0xc6, 0xffdd, 16), new HuffmanElement(0xc7, 0xffde, 16), new HuffmanElement(0xc8, 0xffdf, 16), new HuffmanElement(0xc9, 0xffe0, 16), new HuffmanElement(0xca, 0xffe1, 16), new HuffmanElement(0xd1, 0x7f8, 11), new HuffmanElement(0xd2, 0xffe2, 16), new HuffmanElement(0xd3, 0xffe3, 16), new HuffmanElement(0xd4, 0xffe4, 16), new HuffmanElement(0xd5, 0xffe5, 16), new HuffmanElement(0xd6, 0xffe6, 16), new HuffmanElement(0xd7, 0xffe7, 16), new HuffmanElement(0xd8, 0xffe8, 16), new HuffmanElement(0xd9, 0xffe9, 16), new HuffmanElement(0xda, 0xffea, 16), new HuffmanElement(0xe1, 0xffeb, 16), new HuffmanElement(0xe2, 0xffec, 16), new HuffmanElement(0xe3, 0xffed, 16), new HuffmanElement(0xe4, 0xffee, 16), new HuffmanElement(0xe5, 0xffef, 16), new HuffmanElement(0xe6, 0xfff0, 16), new HuffmanElement(0xe7, 0xfff1, 16), new HuffmanElement(0xe8, 0xfff2, 16), new HuffmanElement(0xe9, 0xfff3, 16), new HuffmanElement(0xea, 0xfff4, 16), new HuffmanElement(0xf0, 0x7f9, 11), new HuffmanElement(0xf1, 0xfff5, 16), new HuffmanElement(0xf2, 0xfff6, 16), new HuffmanElement(0xf3, 0xfff7, 16), new HuffmanElement(0xf4, 0xfff8, 16), new HuffmanElement(0xf5, 0xfff9, 16), new HuffmanElement(0xf6, 0xfffa, 16), new HuffmanElement(0xf7, 0xfffb, 16), new HuffmanElement(0xf8, 0xfffc, 16), new HuffmanElement(0xf9, 0xfffd, 16), new HuffmanElement(0xfa, 0xfffe, 16) #endregion ); int inputDCIndex = 0; po.Invoke("HuffmanEncode", new object[] {bl, inputBlock, inputHuffDC, inputHuffAC, inputDCIndex}); BitList expectedBitList = new BitList(); expectedBitList.Add(false); //Assert.AreEqual(expectedBitList.Count, bl.Count); Assert.Pass(); }
private byte[] decodeScanData(BitList bits) { List<int> validNumbers = new List<int>(); int index = 0; // 16 values are needed in order to find the value of modulo and the length of the encoded message while (validNumbers.Count < 16) { _addNextMCU(validNumbers, bits, ref index); } int length = getLength(validNumbers); int modulo = getModulo(validNumbers); //Remove the values where the length and modulo was encoded validNumbers.RemoveRange(0, 16); byte logOp = (byte)(Math.Log(modulo, 2)); byte steps = (byte)(8 / logOp); int elementsToRead = length * steps * 2; //Only read in the values we need to decode in order to decode the message while (validNumbers.Count < elementsToRead) { _addNextMCU(validNumbers, bits, ref index); } List<byte> messageParts = new List<byte>(); for (int i = 0; i + 1 < elementsToRead; i += 2) { messageParts.Add((byte)(validNumbers[i] + validNumbers[i + 1]).Mod(modulo)); } //Combines each part of each character together, to fully decode the message List<byte> message = new List<byte>(); length = messageParts.Count; for (int i = 0; i < length; i += steps) { byte toAdd = 0; for (int j = 0; j < steps; j++) { toAdd <<= logOp; toAdd += messageParts[i + j]; } message.Add(toAdd); } return message.ToArray(); }
private static byte[] _flush(BitList bits) { while (bits.Count % 8 != 0) { bits.Add(false); } byte[] byteArray = new byte[(int)Math.Ceiling(bits.Count / 8.0)]; int len = byteArray.Length; for (int i = 0; i < len; i++) { for (int j = 0; j < 8; j++) { byteArray[i] = (byte)(byteArray[i] << 1); if (i * 8 + j >= bits.Count) { byteArray[i] = (byte)(byteArray[i] | 0x01); } else { byteArray[i] = (byte)(byteArray[i] | (bits[i * 8 + j] ? 1 : 0)); } } } return byteArray; }
private void _writeScanData() { _s.Restart(); _padCoverImage(); _s.Stop(); _setTimings("_padCoverImage", _s.ElapsedMilliseconds); _s.Restart(); double[][,] channelValues = _splitToChannels(CoverImage); _s.Stop(); _setTimings("_splitToChannels", _s.ElapsedMilliseconds); BitList bits = new BitList(); _encodeMCU(bits, channelValues, CoverImage.Width, CoverImage.Height); _jw.WriteBytes(_flush(bits)); }
private void _encodeMCU(BitList bits, sbyte[][,] YCbCrChannels, int imageWidth, int imageHeight) { if (_quantizedBlocks.Count == 0) { _encodeAndQuantizeValues(YCbCrChannels, imageWidth, imageHeight); } //Encode the secret message in the quantized blocks _encodeMessage(); //Huffman encode the data and save it to the file foreach (var quantizisedBlock in _quantizedBlocks) { HuffmanEncode(bits, quantizisedBlock.Item1, quantizisedBlock.Item2, quantizisedBlock.Item3, quantizisedBlock.Item4); } }
private void _writeScanData() { _padCoverImage(); sbyte[][,] channelValues = _splitToChannels(CoverImage); BitList bits = new BitList(); _encodeMCU(bits, channelValues, CoverImage.Width, CoverImage.Height); _jw.WriteBytes(_flush(bits)); }
// Gets the runsize and returns the amount of read zeroes and the decoded huffman value private int nextValue(BitList bits, ref int index, HuffmanTable huffmanTable, out int zeroes) { HuffmanElement e = null; int i; ushort code = 0; for (i = 1; i <= 16; i++) { code <<= 1; code += (ushort)(bits[index] ? 1 : 0); index++; e = huffmanTable.HasCode(code, i); if (e != null) { break; } } if (e == null) { throw new ArgumentNullException(); } zeroes = (e.RunSize & 0xF0) >> 4; int category = e.RunSize & 0xF; ushort value = 0; for (i = 0; i < category; i++) { value <<= 1; value += (ushort)(bits[index] ? 1 : 0); index++; } return lookupValue(value, category); }
// Read one block in zigzag ordering private List<int> getBlock(BitList bits, ref int index, HuffmanTable DC, HuffmanTable AC) { List<int> validNumbers = new List<int>(); int[] values = new int[64]; int[] zigzag = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; int numberOfElements = 0; int zeroes = 0; // Disregard the DC coefficients values[zigzag[numberOfElements++]] = nextValue(bits, ref index, DC, out zeroes); // Read the remaining 63 AC coefficients in zigzag ordering while (numberOfElements < 64) { int value = nextValue(bits, ref index, AC, out zeroes); if (value == 0 && zeroes == 0) { //EOB while (numberOfElements < 64) { values[zigzag[numberOfElements++]] = 0; } } else { //ZRL and normal for (int i = 0; i < zeroes; i++) { values[zigzag[numberOfElements++]] = 0; } values[zigzag[numberOfElements++]] = value; } } // Adds all the values that's not zeroes to the array-to-be-returned for (int i = 1; i < values.Length; i++) { int element = values[i]; if (element != 0) { validNumbers.Add(element); } } return validNumbers; }
// Read an MCU consisting of 4 Y blocks, 1 block for cb, and 1 block for cr private void _addNextMCU(List<int> validNumbers, BitList bits, ref int index) { for (int i = 0; i < 4; i++) { validNumbers.AddRange(getBlock(bits, ref index, YDCHuffman, YACHuffman)); } for (int i = 0; i < 2; i++) { validNumbers.AddRange(getBlock(bits, ref index, ChrDCHuffman, ChrACHuffman)); } }
public void BitListTest_Construction_Of_One_Length_Bitlist() { BitList bl = new BitList(1); Assert.AreEqual(1, bl.Count); }
public void Enumerable_MultipleValues_LoopsThroughAllAddedValues() { BitList bl = new BitList(8) {true}; //Assert that the first 8 bits are false, and the last value is true Assert.True(!bl.Take(8).Any(bit => bit) && bl.Last()); }
private void _encodeMCU(BitList bits, double[][,] YCbCrChannels, int imageWidth, int imageHeight) { if (_quantizedBlocks.Count == 0) { _quantizeValues(YCbCrChannels, imageWidth, imageHeight); } //Encode the secret message in the quantized blocks _encodeMessage(); //This is where the data is huffman encoded and saved to the file _s.Restart(); foreach (var quantizisedBlock in _quantizedBlocks) { HuffmanEncode(bits, quantizisedBlock.Item1, quantizisedBlock.Item2, quantizisedBlock.Item3, quantizisedBlock.Item4); } _s.Stop(); _setTimings("_Huffmanencoding", _s.ElapsedMilliseconds); }
private void HuffmanEncode(BitList bits, int[,] block8, HuffmanTable huffmanDC, HuffmanTable huffmanAC, int DCIndex) { short diff = (short)(block8[0, 0] - _lastDc[DCIndex]); _lastDc[DCIndex] += diff; if (diff != 0) { byte category = _bitCost(diff); HuffmanElement huffmanCode = huffmanDC.GetElementFromRunSize(0, category); _ushortToBits(bits, huffmanCode.CodeWord, huffmanCode.Length); _ushortToBits(bits, _numberEncoder(diff), category); } else { HuffmanElement EOB = huffmanDC.GetElementFromRunSize(0x00, 0x00); _ushortToBits(bits, EOB.CodeWord, EOB.Length); } int zeroesCounter = 0; for (int i = 1; i < 64; i++) { int x = QuantizationTable.RoadPoints[i, 0], y = QuantizationTable.RoadPoints[i, 1]; if (block8[x, y] == 0) { zeroesCounter++; continue; } while (zeroesCounter >= 16) { HuffmanElement ZRL = huffmanAC.GetElementFromRunSize(0x0F, 0x00); _ushortToBits(bits, ZRL.CodeWord, ZRL.Length); zeroesCounter -= 16; } byte cost = _bitCost((short)Math.Abs(block8[x, y])); HuffmanElement codeElement = huffmanAC.GetElementFromRunSize((byte)zeroesCounter, cost); zeroesCounter = 0; _ushortToBits(bits, codeElement.CodeWord, codeElement.Length); _ushortToBits(bits, _numberEncoder((short)block8[x, y]), cost); } if (zeroesCounter != 0) { //EOB HuffmanElement EOB = huffmanAC.GetElementFromRunSize(0x00, 0x00); _ushortToBits(bits, EOB.CodeWord, EOB.Length); } }
private static void _ushortToBits(BitList bits, ushort number, byte length) { for (int i = 0; i < length; i++) { ushort dummy = 0x01; dummy = (ushort)(dummy << (length - i - 1)); dummy = (ushort)(dummy & number); dummy = (ushort)(dummy >> (length - i - 1)); bits.CheckedAdd((byte)dummy); } }
public void CheckedAdd_Added7TrueInARowAndOneFalse_DoesNotAddEightZeroes() { const int numberOfStartElements = 5; BitList bl = new BitList(numberOfStartElements); for (int i = 0; i < 7; i++) { bl.CheckedAdd(1); } bl.CheckedAdd(0); Assert.AreEqual(8 + numberOfStartElements, bl.Count); for (int i = 8 + numberOfStartElements; i < 8 + numberOfStartElements; i++) { Assert.False(bl[i]); } }
private BitList findScanData() { byte a; findMarker(0xda); for (int i = 0; i < 12; i++) { file.ReadByte(); } // Writes scandata to List List<byte> scanData = new List<byte>(); int length = (int)file.BaseStream.Length; while (file.BaseStream.Position < length) { a = file.ReadByte(); if (a == 0xff) { byte b = file.ReadByte(); if (b != 0) { //If bytes are actually a marker break; } } scanData.Add(a); } // Convert each byte to bits BitList bits = new BitList(); foreach (byte current in scanData) { byte mask = 1; for (int i = 0; i < 8; i++) { bits.Add((current & (mask << (7 - i))) >> (7 - i)); } } return bits; }