public CodepointValueAndOverflowLength findFirstMatchingCodepoint(byte[] codepoint) { CodepointValueAndOverflowLength result; HackBinaryTreeElement currentElement = root; int codepointIndex = 0; while (currentElement.left != null && currentElement.right != null) { if (codepoint[codepointIndex] == 0) { currentElement = currentElement.left; } else { currentElement = currentElement.right; } codepointIndex++; } result.value = currentElement.value; result.overflowLength = (UInt16)(codepoint.Length - codepointIndex); return(result); }
public Stack <bool> unwind() { Stack <bool> result = new Stack <bool>(); HackBinaryTreeElement currentElement = this; while (currentElement.parent != null) { result.Push(!currentElement.isLeft); currentElement = currentElement.parent; } return(result); }
public HackBinaryTree() { freeNodesAtCurrentDepth = new Queue <HackBinaryTreeElement>(); root = new HackBinaryTreeElement(); root.parent = null; root.left = new HackBinaryTreeElement(); root.left.isLeft = true; root.left.parent = root; root.right = new HackBinaryTreeElement(); root.right.isLeft = false; root.right.parent = root; freeNodesAtCurrentDepth.Enqueue(root.left); freeNodesAtCurrentDepth.Enqueue(root.right); }
public void addDepth() { Queue <HackBinaryTreeElement> tempFreeNodesAtCurrentDepth = new Queue <HackBinaryTreeElement>(); while (freeNodesAtCurrentDepth.Count != 0) { HackBinaryTreeElement currentNode = freeNodesAtCurrentDepth.Dequeue(); currentNode.left = new HackBinaryTreeElement(); currentNode.left.isLeft = true; currentNode.left.parent = currentNode; currentNode.right = new HackBinaryTreeElement(); currentNode.right.isLeft = false; currentNode.right.parent = currentNode; tempFreeNodesAtCurrentDepth.Enqueue(currentNode.left); tempFreeNodesAtCurrentDepth.Enqueue(currentNode.right); } freeNodesAtCurrentDepth = tempFreeNodesAtCurrentDepth; }
public static JpgHeaders readJpgFileHeader(ref byte[] fileBytes) { JpgHeaders jpgFileHeaders = new JpgHeaders(); jpgFileHeaders.fileOk = true; jpgFileHeaders.imageDataStartOffsetInBytes = 2; jpgFileHeaders.isLittleEndian = true; jpgFileHeaders.codeToSignedValueDictionary = new Dictionary <string, Int16>(); jpgFileHeaders.codeToSignedValueDictionary.Add("", 0); jpgFileHeaders.signedValueToCodeDictionary = new Dictionary <Int16, string>(); jpgFileHeaders.signedValueToCodeDictionary.Add(0, ""); jpgFileHeaders.huffmanCodesBinaryTrees = new Dictionary <byte, HuffmanCodesBinaryTree>(); Int16 rangeMin = -2047; Int16 rangeMax = 2047; Int16 currentStartingMinValue = -1; Int16 currentMinValue = 0; Int16 currentMaxValue = 0; byte codeLength = 1; while (currentMinValue > rangeMin && currentMaxValue < rangeMax) { Int16 numberOfValuesInCurrentHalfIteration = (Int16)(1 << (codeLength - 1)); Int16 currentValueIteration = 0; while (currentValueIteration < numberOfValuesInCurrentHalfIteration) { currentMinValue = (Int16)(currentStartingMinValue + currentValueIteration); jpgFileHeaders.codeToSignedValueDictionary.Add(binaryToString(currentValueIteration, codeLength), currentMinValue); jpgFileHeaders.signedValueToCodeDictionary.Add(currentMinValue, binaryToString(currentValueIteration, codeLength)); currentValueIteration++; } currentValueIteration = 0; while (currentValueIteration < numberOfValuesInCurrentHalfIteration) { currentMaxValue = (Int16)(numberOfValuesInCurrentHalfIteration + currentValueIteration); jpgFileHeaders.codeToSignedValueDictionary.Add(binaryToString((Int16)(numberOfValuesInCurrentHalfIteration + currentValueIteration), codeLength), currentMaxValue); jpgFileHeaders.signedValueToCodeDictionary.Add(currentMaxValue, binaryToString((Int16)(numberOfValuesInCurrentHalfIteration + currentValueIteration), codeLength)); currentValueIteration++; } currentStartingMinValue -= (Int16)(1 << (codeLength)); codeLength++; } MemoryStreamWithTypedReads binaryReader = new MemoryStreamWithTypedReads(fileBytes); UInt16 readMarker; bool firstPass = true; bool dataNotStarted = true; while (((readMarker = binaryReader.readUInt16()) != JpgMarkers.endOfImage) && jpgFileHeaders.fileOk && dataNotStarted) { dataNotStarted = readMarker != JpgMarkers.startOfScan; if (dataNotStarted) { switch (readMarker) { case (JpgMarkers.startOfHuffmanTables): { UInt16 expectedTablesLength = binaryReader.readUInt16(); jpgFileHeaders.imageDataStartOffsetInBytes += 2 + expectedTablesLength; for (UInt64 readBytes = 2; readBytes < expectedTablesLength; readBytes++) { UInt32 currentTableLength = 0; byte classAndIndetifierByte = binaryReader.readByte(); currentTableLength += 8; readBytes++; HuffmanCodesBinaryTree huffmanCodesBinaryTree = new HuffmanCodesBinaryTree(); ref HackBinaryTree currentBinaryTree = ref huffmanCodesBinaryTree.binaryTree; byte maxCodeLength = 0; byte[] extractedHuffmanCodeCounts = new byte[16]; for (int lengthOfCode = 1; lengthOfCode <= 16; lengthOfCode++) { extractedHuffmanCodeCounts[lengthOfCode - 1] = binaryReader.readByte(); currentTableLength += 8; readBytes++; } for (int lengthOfCode = 1; lengthOfCode <= 16; lengthOfCode++) { for (int codeIndex = 0; codeIndex < extractedHuffmanCodeCounts[lengthOfCode - 1]; codeIndex++) { maxCodeLength = (byte)lengthOfCode; HackBinaryTreeElement nextElement = currentBinaryTree.freeNodesAtCurrentDepth.Peek(); byte value = binaryReader.readByte(); huffmanCodesBinaryTree.valueToHuffmanCodeDictionary.Add(value, nextElement.unwind()); currentBinaryTree.addValue(value); currentTableLength += 8; readBytes++; } currentBinaryTree.addDepth(); } huffmanCodesBinaryTree.maxCodeLength = maxCodeLength; huffmanCodesBinaryTree.inFileLength = currentTableLength; jpgFileHeaders.huffmanCodesBinaryTrees.Add(classAndIndetifierByte, huffmanCodesBinaryTree); } } break;