Esempio n. 1
0
def read_tree(bitreader):
    '''Read a description of a Huffman tree from the given bit reader,
    and construct and return the tree. When this function returns, the
    bit reader should be ready to read the next bit immediately
    following the tree description.

    Huffman trees are stored in the following format:
      * TreeLeaf is represented by the two bits 01, followed by 8 bits
          for the symbol at that leaf.
      * TreeLeaf that is None (the special "end of message" character)
          is represented by the two bits 00.
      * TreeBranch is represented by the single bit 1, followed by a
          description of the left subtree and then the right subtree.

    Args:
      bitreader: An instance of bitio.BitReader to read the tree from.

    Returns:
      A Huffman tree constructed according to the given description.
    '''

    bit = bitreader.readbit()
    if bit == 1:  # branch is indicated by a 1
        left = read_tree(bitreader)
        right = read_tree(bitreader)
        tree_part = huffman.TreeBranch(left, right)
    elif bit == 0:  # leaf is indicated by a 0
        bit = bitreader.readbit()
        if bit == 1:  # 01 is a 'symbol'
            symbol = bitreader.readbits(8)
            tree_part = huffman.TreeLeaf(symbol)
        elif bit == 0:  # 00 is the EOF symbol
            tree_part = huffman.TreeLeaf(None)

    return tree_part
Esempio n. 2
0
 def recurse(bitreader):
     if bitreader.readbit():  # if we get a 1, that means we have a branch
         left = recurse(bitreader)  # find left tree
         right = recurse(bitreader)  # find right tree
         return huffman.TreeBranch(left, right)  # return tree branch
     else:  # we got a 0
         if bitreader.readbit():  # we got a 01
             return huffman.TreeLeaf(bitreader.readbits(8))  # read byte
         else:
             return huffman.TreeLeaf(None)  # return empty tree leaf
Esempio n. 3
0
 def re_tree(bitreader):
     bit = bitreader.readbit()
     if bit == 1:
         tree = huffman.TreeBranch(None, None)
         tree.left = re_tree(bitreader)
         tree.right = re_tree(bitreader)
         return tree
     elif bit == 0:
         anotherbit = bitreader.readbit()
         if anotherbit == 0:
             return huffman.TreeLeaf(None)
         else:
             leafval = bitreader.readbits(8)
             return huffman.TreeLeaf(leafval)
Esempio n. 4
0
def decode_byte(tree, bitreader):
    """
    Reads bits from the bit reader and traverses the tree from
    the root to a leaf. Once a leaf is reached, bits are no longer read
    and the value of that leave is returned.

    Args:
      bitreader: An instance of bitio.BitReader to read the tree from.
      tree: A Huffman tree.

    Returns:
      Next byte of the compressed bit stream.
    """
    #read bits from the bit reader
    #traverse the tree based on bits
    current = tree

    while True:
        bit = bitreader.readbit()

        if bit:
            #go right
            current = current.right
        else:
            #go left
            current = current.left

        #if a leaf is reached, stop searching
        if type(current) == type(huffman.TreeLeaf(0)):
            break

    # return value of leaf
    return current.value
Esempio n. 5
0
def write_tree(tree, bitwriter):
    '''Write the specified Huffman tree to the given bit writer.  The
    tree is written in the format described above for the read_tree
    function.

    DO NOT flush the bit writer after writing the tree.

    Args:
      tree: A Huffman tree.
      bitwriter: An instance of bitio.BitWriter to write the tree to.
    '''

    if type(tree) == type(huffman.TreeBranch(0, 0)):
        # tree branch bit code is 1
        bitwriter.writebit(True)
        # write the bits for the children
        write_tree(tree.left, bitwriter)
        write_tree(tree.right, bitwriter)
    elif type(tree) == type(huffman.TreeLeaf(0)):
        if tree.value == None:
            # EOF bit code is 00
            bitwriter.writebit(False)
            bitwriter.writebit(False)
        else:
            # code for a leaf is 01 followed by the 8 bit leaf symbol
            bitwriter.writebit(False)
            bitwriter.writebit(True)
            symbol = tree.value
            bitwriter.writebits(symbol, 8)
Esempio n. 6
0
def read_tree (bitreader):
    '''Read a description of a Huffman tree from the given bit reader,
    and construct and return the tree. When this function returns, the
    bit reader should be ready to read the next bit immediately
    following the tree description.

    Huffman trees are stored in the following format:
      * TreeLeafEndMessage is represented by the two bits 00.
      * TreeLeaf is represented by the two bits 01, followed by 8 bits
          for the symbol at that leaf.
      * TreeBranch is represented by the single bit 1, followed by a
          description of the left subtree and then the right subtree.

    Args:
      bitreader: An instance of bitio.BitReader to read the tree from.

    Returns:
      A Huffman tree constructed according to the given description.
    '''
    #the function uses recursion to build from the bottom up
    first_bit = bitreader.readbit()
    if first_bit == 1:
        #create a tree branch
        return huffman.TreeBranch(read_tree(bitreader), read_tree(bitreader))
    else:
        second_bit = bitreader.readbit()
        if second_bit == 0:
            #reached end of tree
            return huffman.TreeLeafEndMessage()
        else:
            #create a tree leaf
            return huffman.TreeLeaf(bitreader.readbits(8))
Esempio n. 7
0
def write_tree(tree, bitwriter):
    '''Write the specified Huffman tree to the given bit writer.  The
        tree is written in the format described above for the read_tree
        function.

        DO NOT flush the bit writer after writing the tree.

        Args:
        tree: A Huffman tree.
        bitwriter: An instance of bitio.BitWriter to write the tree to.
    '''
    if type(tree) == huffman.TreeLeaf:
        # check if tree is a leaf
        if tree.value == None: # if empty, write '00'
            bitwriter.writebit(0)
            bitwriter.writebit(0)
        else: # else, write '01' and following 8 bits
            bitwriter.writebit(0)
            bitwriter.writebit(1)
            huffman.TreeLeaf(bitwriter.writebits(tree.value, 8))

    elif type(tree) == huffman.TreeBranch:
        # if tree is a branch, then recursively write in the left and
        # right children/branches/subtree(s)
        bitwriter.writebit(1)
        left = write_tree(tree.left, bitwriter)
        right = write_tree(tree.right, bitwriter)
Esempio n. 8
0
 def construct_tree(bitreader):
     bit = bitreader.readbit()
     if bit == 1:
         #need a branch, construct a new one and its branchs
         new_branch = huffman.TreeBranch(None, None)
         new_branch.left = construct_tree(bitreader)
         new_branch.right = construct_tree(bitreader)
         return new_branch
     elif bit == 0:
         bit2 = bitreader.readbit()
         if bit2 == 0:
             #eof file character
             return huffman.TreeLeaf(None)
         else:
             #return the value of the next 8 bits corresponding to the leaf
             val = bitreader.readbits(8)
             return huffman.TreeLeaf(val)
Esempio n. 9
0
def read_tree(bitreader):
	'''Read a description of a Huffman tree from the given bit reader,
	and construct and return the tree. When this function returns, the
	bit reader should be ready to read the next bit immediately
	following the tree description.

	Huffman trees are stored in the following format:
	* TreeLeaf is represented by the two bits 01, followed by 8 bits
	for the symbol at that leaf.
	* TreeLeaf that is None (the special "end of message" character)
	is represented by the two bits 00.
	* TreeBranch is represented by the single bit 1, followed by a
	description of the left subtree and then the right subtree.

	Args:
	bitreader: An instance of bitio.BitReader to read the tree from.

	Returns:
	A Huffman tree constructed according to the given description.
	'''
	#since bitreader is an instance of bitio.BitReader, we use readbit() to read first bit
	first_bit = bitreader.readbit()
	#if first bit is 1 means start from 1, it is branch
	if first_bit == 1:
		#read left sub tree until reach leaf		
		leftsub = read_tree(bitreader)
		#read right sub tree until reach leaf
		rightsub = read_tree(bitreader)
		#build the huffman tree branch
		Branch = huffman.TreeBranch(leftsub, rightsub)
		return Branch

	else:
		#there is a leaf
		second_bit = bitreader.readbit()
		#if second bit is 0 means EOF reached
		if second_bit == 0:
			#build the huffman tree leaf
			Eof = huffman.TreeLeaf(None)
			return Eof
		elif second_bit == 1:
			#if second bit is 1 means there is a character, read the bits of character
			value = bitreader.readbits(8)
			#build the huffman tree leaf and store the 8 bits
			valueleaf = huffman.TreeLeaf(value)
			return valueleaf
Esempio n. 10
0
    def recurse_read(bitreader, huffman_tree=None):
        # read the first bit
        bit_read = bitreader.readbit()

        # if the first bit is 1, it is a TreeBranch
        if bit_read == 1:
            left_leaf = recurse_read(bitreader)
            right_leaf = recurse_read(bitreader)
            huffman_tree = huffman.TreeBranch(left_leaf, right_leaf)
            return huffman_tree

        # there is two cases when the first bit is 0
        elif bit_read == 0:
            bit_read = bitreader.readbit()

            # case of a none TreeLeaf
            if bit_read == 0:
                leaf = huffman.TreeLeaf(None)
            # case of a normal TreeLeaf
            elif bit_read == 1:
                # use bitreader to get value from the following byte
                byte_read = bitreader.readbits(8)
                leaf = huffman.TreeLeaf(byte_read)
            return leaf
Esempio n. 11
0
def read_tree(bitreader):
    '''Read a description of a Huffman tree from the given bit reader,
        and construct and return the tree. When this function returns, the
        bit reader should be ready to read the next bit immediately
        following the tree description.

        Huffman trees are stored in the following format:
        * TreeLeaf is represented by the two bits 01, followed by 8 bits
        for the symbol at that leaf.
        * TreeLeaf that is None (the special "end of message" character)
        is represented by the two bits 00.
        * TreeBranch is represented by the single bit 1, followed by a
        description of the left subtree and then the right subtree.

        Args:
        bitreader: An instance of bitio.BitReader to read the tree from.

        Returns:
        A Huffman tree constructed according to the given description.
    '''
    # check the first bit
    firstbit = bitreader.readbit()

    if firstbit == 0: # if 0, leaf.
        secondbit = bitreader.readbit() # check second bit

        if secondbit == 0: # if leaf is '00', then EOM
            return huffman.TreeLeaf(None)
        else: # if leaf is '01', then get those bytes sis
            return huffman.TreeLeaf(bitreader.readbits(8))

    else: # otherwise first bit should be a 1, so it's a branch
        # return the children! (left and right)
        left = read_tree(bitreader)
        right = read_tree(bitreader)
        return huffman.TreeBranch(left, right)
Esempio n. 12
0
def read_tree(bitreader):
    # bit == 1, TreeBranch
    if bitreader.readbit() == 1:
        tree = huffman.TreeBranch(read_tree(bitreader), read_tree(bitreader))
        return tree
    # bit == 0, could be either TreeLeaf(value) or TreeLeafEndMessage()
    else:
        # bit == 1, 01 - TreeLeaf(value)
        if bitreader.readbit() == 1:
            # read 8 bits for the symbol at this leaf
            value = bitreader.readbits(8)
            leaf = huffman.TreeLeaf(value)
            return leaf
        # bit == 0, 00 - TreeLeafEndMessage()
        else:
            endMsg = huffman.TreeLeafEndMessage()
            return endMsg
Esempio n. 13
0
    def get_branch(bitreader, tree=None):
        bit = bitreader.readbit()

        if bit == 1:

            left = get_branch(bitreader)
            right = get_branch(bitreader)
            tree = huffman.TreeBranch(left, right)
            return tree

        elif bit == 0:
            bit = bitreader.readbit()

            if bit == 1:
                byte = bitreader.readbits(8)
                leaf = huffman.TreeLeaf(byte)

            elif bit == 0:
                leaf = huffman.TreeLeafEndMessage()

            return leaf
Esempio n. 14
0
def read_tree(bitreader):
    '''Read a description of a Huffman tree from the given bit reader,
    and construct and return the tree. When this function returns, the
    bit reader should be ready to read the next bit immediately
    following the tree description.

    Huffman trees are stored in the following format:
      * TreeLeafEndMessage is represented by the two bits 00.
      * TreeLeaf is represented by the two bits 01, followed by 8 bits
          for the symbol at that leaf.
      * TreeBranch is represented by the single bit 1, followed by a
          description of the left subtree and then the right subtree.

    Args:
      bitreader: An instance of bitio.BitReader to read the tree from.

    Returns:
      A Huffman tree constructed according to the given description.
    '''
    tree_dict = {  # maps the bit sequence to the tree instance
        '00': huffman.TreeLeafEndMessage(),
        '01': lambda i: huffman.TreeLeaf(i),
        '1': lambda l, r: huffman.TreeBranch(l, r)
    }

    b1 = bitreader.readbit()  # read first bit
    if b1 == 1:  # if first bit is a 1 it must be a branch
        left = read_tree(bitreader)  # apply recursively over left and right
        right = read_tree(bitreader)  # branch
        tree = tree_dict['1'](left, right)
    else:  # otherwise its either a endLeaf or valueLeaf
        b2 = bitreader.readbit()
        b = b1 + b2
        if b == 0:
            tree = tree_dict['00']
        elif b == 1:
            tree = tree_dict['01'](bitreader.readbits(8))
    # print(tree)
    return tree
Esempio n. 15
0
def read_tree(bitreader):
    '''Read a description of a Huffman tree from the given bit reader,
    and construct and return the tree. When this function returns, the
    bit reader should be ready to read the next bit immediately
    following the tree description.

    Huffman trees are stored in the following format:
      * TreeLeafEndMessage is represented by the two bits 00.
      * TreeLeaf is represented by the two bits 01, followed by 8 bits
          for the symbol at that leaf.
      * TreeBranch is represented by the single bit 1, followed by a
          description of the left subtree and then the right subtree.

    Args:
      bitreader: An instance of bitio.BitReader to read the tree from.

    Returns:
      A Huffman tree constructed according to the given description.
    '''
    bit = bitreader.readbit()
    # if the the first bit is 0, need to read the next bit
    if bit == 0:
        bit = bitreader.readbit()
        if bit == 1:
            # if the combination is 01, create a leaf with the next byte
            byte = bitreader.readbits(8)
            tree = huffman.TreeLeaf(byte)
        else:
            # if the combination is 00, create an end message
            tree = huffman.TreeLeafEndMessage()

    else:  # if the first bit is 1, create a branch and recurse on the left side
        # then the right side
        tree = huffman.TreeBranch(read_tree(bitreader), read_tree(bitreader))

    return tree
Esempio n. 16
0
    util.write_tree(tree, writer)
    writer.flush()

with open("simple.txt", 'rb') as file:
    reader = bitio.BitReader(file)
    new_tree = util.read_tree(reader)

with open("simple.txt", 'wb') as file:
    writer = bitio.BitWriter(file)

    print("Hey bitch")
    util.write_tree(new_tree, writer)
    writer.flush()

#==============================================================================
#==============================================================================
with open("simple.txt",'wb') as f:
    f.write(b'00')
with open("simple.txt", 'rb') as file:
    reader = bitio.BitReader(file)
    tree = huffman.TreeBranch(huffman.TreeBranch(huffman.TreeLeaf(ord('A')),huffman.TreeLeaf(None)),huffman.TreeLeaf(ord('B')))
    print(util.decode_byte(tree,reader))
"""
tree = huffman.TreeBranch(
    huffman.TreeBranch(huffman.TreeLeaf(ord('A')), huffman.TreeLeaf(None)),
    huffman.TreeLeaf(ord('B')))
table = huffman.make_encoding_table(tree)
encoded = table[65]
for bit in table[None]:
    print(bit)
Esempio n. 17
0
 def read_treeLeaf():
     return huffman.TreeLeaf(bitreader.readbits(8))
Esempio n. 18
0
 def read_end():
     return huffman.TreeLeaf(None)