Beispiel #1
0
 public HuffmanCodesBinaryTree()
 {
     valueToHuffmanCodeDictionary = new Dictionary <byte, Stack <bool> >();
     binaryTree = new HackBinaryTree();
 }
Beispiel #2
0
        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;