Example #1
0
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()

    outputBytes = bytearray()

    for y in range(img.shape[0]):
        for x in range(img.shape[1]):
            for c in range(img.shape[2]):
                outputBytes.append(img[y, x, c])

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    outputFile.write('%s\n' % headerText)
    outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2]))
    outputFile.write(outputBytes)

    # Print information about the compression

    inSize = img.shape[0] * img.shape[1] * img.shape[2]
    outSize = len(outputBytes)

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
Example #2
0
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.

    startTime = time.time()

    outputBytes = bytearray()

    for y in range(img.shape[0]):
        for x in range(img.shape[1]):
            for c in range(img.shape[2]):
                outputBytes.append(img[y, x, c])

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    outputFile.write('%s\n' % headerText)
    outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2]))
    outputFile.write(outputBytes)

    # Print information about the compression

    inSize = img.shape[0] * img.shape[1] * img.shape[2]
    outSize = len(outputBytes)

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
Example #3
0
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()

    # outputBytes = []
    outputBytes = bytearray()

    diff = []

    # it's a single-channel image
    if len(img.shape) == 2:
        for y in range(img.shape[0]):
            for x in range(img.shape[1]):
                # Predictive encoding
                prediction = int(
                    img[y - 1,
                        x]) + (int(img[y, x - 1]) - int(img[y - 1, x - 1])) / 2
                diff.append(int(img[y, x]) - int(prediction))

    else:  # it's a multi-channel image

        for y in range(img.shape[0]):
            for x in range(img.shape[1]):
                for c in range(img.shape[2]):
                    # Predictive encoding
                    prediction = int(img[y - 1, x, c]) + (
                        int(img[y, x - 1, c]) - int(img[y - 1, x - 1, c])) / 2
                    diff.append(int(img[y, x, c]) - int(prediction))

    # print(diff)
    # construct initial dictionary
    dict_size = 256
    dictionary = {
        struct.pack("h", i): i + 256
        for i in xrange(-dict_size, dict_size)
    }

    # LZW encode the diff array
    s = ''
    for i in range(len(diff)):

        x = struct.pack('h', diff[i])
        temp = s + x
        if temp in dictionary:
            s = temp
        else:
            s_in = dictionary[s]
            s1 = s_in >> 8
            s2 = s_in & 255
            outputBytes.append(s1)
            outputBytes.append(s2)
            if len(dictionary) < 65536:
                dictionary[temp] = dict_size
                dict_size += 1
            s = x

    # encode the last s
    s_in = dictionary[s]
    s1 = s_in >> 8
    s2 = s_in & 255
    outputBytes.append(s1)
    outputBytes.append(s2)
    # print(dictionary)

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    outputFile.write('%s\n' % headerText)
    outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2]))
    outputFile.write(str(outputBytes))

    # Print information about the compression

    inSize = img.shape[0] * img.shape[1] * img.shape[2]
    outSize = len(outputBytes)

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
Example #4
0
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of components in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()

    outputBytes = bytearray()

    # initialize dictionary
    d = {}
    counter = 256
    for i in range(-counter, counter):
        d[str(i)] = i
    # Set Dictionary limit

    # Make a list to hold bytes
    tempBytes = []
    # A counter for the number of bytes
    numBytes = 0
    multichannel = True
    # for a single channel image
    if (len(img.shape) == 2):
        multichannel = False
        # Go through whole image
        for y in range(img.shape[0]):
            for x in range(img.shape[1]):
                # Initialize prediction to image value
                prediction = img[y][x]
                #"""
                # Modify prediction to show the difference between prior pixels and current pixel
                if (x != 0):
                    prediction = prediction - img[y][x - 1]
                elif (y != 0):
                    prediction = prediction - img[y - 1][x]
                else:
                    prediction = prediction - (img[y][x - 1] / 3 +
                                               img[y - 1][x] / 3 +
                                               img[y - 1][x - 1] / 3)
                #"""
                # Add the predicted value to the bytestream
                tempBytes.append(prediction)
                numBytes += 1

    # Multi-Channel
    else:

        # Go through whole image and channels
        for y in range(img.shape[0]):
            for x in range(img.shape[1]):
                for c in range(img.shape[2]):
                    # Do predictive encoding

                    # Initialize prediction to image value
                    prediction = img[y][x][c]
                    # Modify prediction to show the difference between prior pixels and current pixel
                    #""""
                    if (x != 0):
                        prediction = prediction - img[y][x - 1][c]
                    elif (y != 0):
                        prediction = prediction - img[y - 1][x][c]
                    else:
                        prediction = prediction - (img[y][x - 1][c] / 3 +
                                                   img[y - 1][x][c] / 3 +
                                                   img[y - 1][x - 1][c] / 3)
                    #""""
                    # Add the predicted value to the bytestream
                    tempBytes.append(prediction)
                    numBytes += 1

    # Using a string variable as it allows for concatenation
    s = ""
    # Set s to the first value of the bytestream
    s = str(tempBytes[0])
    # Go through all bytes
    for i in range(1, numBytes):
        # Do LZW encoding
        # If trying to add entry larger than max size of the dictionary reinitialize the dictionary
        if (counter >= twoBytes):
            counter = 256
            d = {}
            for i in range(-counter, counter):
                d[str(i)] = i

        # Add the next byte to the current string. Uses a delimeter to distinguish numbers
        w = s + "|" + str(tempBytes[i])
        # Checking if it has been seen before
        if w in d:
            s = w
        else:
            # Output bytes by splitting integer into two bytes, this allows for a larger dictionary
            outputBytes.append((int(d[s]) >> 8) & 0xFF)
            outputBytes.append(int(d[s]) & 0xFF)
            # Add to dictionarry
            d[w] = counter
            counter += 1
            s = str(int(tempBytes[i]))
    # Check if the last byte was added or not
    if s in d:
        outputBytes.append((int(d[s]) >> 8) & 0xFF)
        outputBytes.append(int(d[s]) & 0xFF)

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    outputFile.write('%s\n' % headerText)
    if (multichannel):
        outputFile.write('%d %d %d\n' %
                         (img.shape[0], img.shape[1], img.shape[2]))

    else:
        one = 1
        outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1]), one)
    outputFile.write(outputBytes)

    # Print information about the compression
    if (multichannel):
        inSize = img.shape[0] * img.shape[1] * img.shape[2]
    else:
        inSize = img.shape[0] * img.shape[1]
    outSize = len(outputBytes)

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
Example #5
0
def compress(inputFile, outputFile):
    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()

    # outputBytes = np.array([],dtype = np.uint16)
    tempBytes = []
    channels = 0

    # -256 - 0 maps to 0 - 256, 1-255 mapps to 257 - 511
    baseDict = genDict()

    if len(img.shape) == 2:
        channels = 1
    elif len(img.shape) == 3:
        channels = 3
    else:
        print("unrecognized image format")
        return

    pArray = []

    # if 1 channel, loop through every pixel
    if (channels == 1):
        for x in range(img.shape[0]):
            for y in range(img.shape[1]):

                # initial pixel, don't make prediction
                if (x == 0 and y == 0):
                    pArray.append(int(img[0, 0]))
                else:
                    # make prediction using previous pixel
                    if x == 0:
                        pArray.append(int(img[x, y]) - int(img[x, y - 1]))
                    else:
                        pArray.append(int(img[x, y]) - int(img[x - 1, y]))

                        # Image has 3 channels, loop through all pixels and channels
    else:
        for x in range(img.shape[0]):
            for y in range(img.shape[1]):
                for c in range(img.shape[2]):

                    # Initial pixel, no prediction
                    if (x == 0 and y == 0):
                        pArray.append(int(img[0, 0, c]))
                    else:

                        if x == 0:
                            pArray.append(
                                int(img[x, y, c]) - int(img[x, y - 1, c]))
                        else:
                            pArray.append(
                                int(img[x, y, c]) - int(img[x - 1, y, c]))

    # number of symbols to encode
    numSymbols = img.shape[0] * img.shape[1] * channels

    # LZW Compression
    s = str(pArray[0])
    nextDictIndex = len(baseDict)

    for i in range(1, numSymbols):
        x = str(pArray[i])

        if s + "," + x in baseDict:
            s = s + "," + x
        else:

            tempBytes.append(baseDict[s])
            baseDict[s + "," + x] = np.uint16(nextDictIndex)
            nextDictIndex += 1
            s = x

    tempBytes.append(baseDict[s])
    outputBytes = np.array(tempBytes, dtype=np.uint16)

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    stringImgShape = []

    for num in img.shape:
        stringImgShape.append(str(num))

    outputFile.write('%s\n' % headerText)
    outputFile.write(' '.join(stringImgShape) + '\n')
    outputFile.write(outputBytes)

    # Print information about the compression

    inSize = numSymbols
    outSize = len(outputBytes)

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
Example #6
0
def compress( inputFile, outputFile ):

  # Read the input file into a numpy array of 8-bit values
  #
  # The img.shape is a 3-type with rows,columns,channels, where
  # channels is the number of component in each pixel.  The img.dtype
  # is 'uint8', meaning that each component is an 8-bit unsigned
  # integer.

  img = netpbm.imread( inputFile ).astype('uint8')

  # Compress the image
  #
  # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
  #
  # Note that single-channel images will have a 'shape' with only two
  # components: the y dimensions and the x dimension.  So you will
  # have to detect this and set the number of channels accordingly.
  # Furthermore, single-channel images must be indexed as img[y,x]
  # instead of img[y,x,1].  You'll need two pieces of similar code:
  # one piece for the single-channel case and one piece for the
  # multi-channel case.

  startTime = time.time()

  outputBytes = bytearray()

  # Initialize dictionary
  maxsize = 65536
  dict_size = 256
  d = initializeDictionary(dict_size)
  s = ''

  for y in range(img.shape[0]):
    for x in range(img.shape[1]):
      for c in range(img.shape[2]):
        fp = 0
        if(len(img.shape) > 2):
            #fp = getprediction(img,x,y,c,True)
            if(x > 0):
                fp = img[y,x-1,c]
            e = img[y,x,c] - fp
        else:
            #fp = getprediction(img,x,y,0,False)
            if(x > 0):
                fp = img[y,x-1]
            e = img[y,x] - fp
        if(s + chr(e) in d):
            s += chr(e)
        else:
            #sq = convertchar2num(d[s])
            sq = d[s]
            if(len(sq) < 2):
                sq = chr(0) + sq
            outputBytes.append(sq[0])
            outputBytes.append(sq[1])
            d[s + chr(e)] = convertnum2char(dict_size)
            dict_size += 1
            if(dict_size > maxsize):
                dict_size = 256
                d = initializeDictionary(dict_size)
            s = chr(e)
  sq = d[s]
  if(len(sq) < 2):
    sq = chr(0) + sq
  outputBytes.append(sq[0])
  outputBytes.append(sq[1])
  endTime = time.time()

  # Output the bytes
  #
  # Include the 'headerText' to identify the type of file.  Include
  # the rows, columns, channels so that the image shape can be
  # reconstructed.

  outputFile.write( '%s\n'       % headerText )
  if len(img.shape) > 2:
      outputFile.write( '%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2]) )
  else:
      outputFile.write( '%d %d\n' % (img.shape[0], img.shape[1]))
  outputFile.write( outputBytes )

  # Print information about the compression

  if len(img.shape) > 2:
      inSize  = img.shape[0] * img.shape[1] * img.shape[2]
  else:
      inSize = img.shape[0]*img.shape[1]

  outSize = len(outputBytes)

  sys.stderr.write( 'Input size:         %d bytes\n' % inSize )
  sys.stderr.write( 'Output size:        %d bytes\n' % outSize )
  sys.stderr.write( 'Compression factor: %.2f\n' % (inSize/float(outSize)) )
  sys.stderr.write( 'Compression time:   %.2f seconds\n' % (endTime - startTime) )
Example #7
0
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()

    dimensions = len(img.shape)

    # if single channel
    if dimensions == 2:

        # Empty dictionary
        d = {}
        # Current dictionary index
        dict_index = 0
        # Previous value
        prev = 0

        for i in range(-255, 256):
            # Stores the binary value
            d[(struct.pack('>h', i))] = i + 255
            dict_index = i + 255

        outputBytes = bytearray()
        # p is the byte pattern that will be passed into the dictionary
        p = ""
        p_c = ""

        for y in range(img.shape[0]):
            for x in range(img.shape[1]):

                # c is the current byte being analyzed
                c = int(img[y][x]) - int(prev)
                prev = img[y][x]

                bc = struct.pack('>h', c)
                p_c = p + bc

                # if the character c is already in the dictionary add it to the present character stream
                if p_c in d:
                    p = p_c
                else:
                    val = struct.pack('>H', d[p])
                    b1, b2 = struct.unpack('>BB', val)
                    outputBytes.append(b1)
                    outputBytes.append(b2)
                    if dict_index < 65535:
                        dict_index += 1
                        d[p_c] = dict_index
                    p = bc
        outputFile.write('%d %d\n' % (img.shape[0], img.shape[1]))
        outputBytes.append(img[y, x])

    # if multichannel
    elif dimensions > 2:

        # Empty dictionary
        d = {}
        # Current dictionary index
        dict_index = 0

        # Previous values
        prev = []

        for i in range(img.shape[2]):
            prev.append(0)

        for i in range(-255, 256):
            # Stores the binary value
            d[(struct.pack('>h', i))] = i + 255
            dict_index = i + 255

        outputBytes = bytearray()
        # p is the byte pattern that will be passed into the dictionary
        p = ""
        p_c = ""

        for y in range(img.shape[0]):
            for x in range(img.shape[1]):
                for channel in range(img.shape[2]):

                    # c is the current byte being analyzed
                    c = int(img[y][x][channel]) - int(prev[channel])
                    prev[channel] = img[y][x][channel]

                    bc = struct.pack('>h', c)
                    p_c = p + bc

                    # if the character c is already in the dictionary add it to the present character stream
                    if p_c in d:
                        p = p_c
                    else:
                        val = struct.pack('>H', d[p])
                        b1, b2 = struct.unpack('>BB', val)
                        outputBytes.append(b1)
                        outputBytes.append(b2)
                        if dict_index < 65535:
                            dict_index += 1
                            d[p_c] = dict_index
                        p = bc
        outputFile.write('%d %d %d\n' %
                         (img.shape[0], img.shape[1], img.shape[2]))
        outputBytes.append(img[y, x, channel])

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    outputFile.write('%s\n' % headerText)
    outputFile.write(outputBytes)

    # Print information about the compression
    inSize = img.shape[0] * img.shape[1]

    outSize = len(outputBytes)

    endTime = time.time()

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.
    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()
    outputBytes = bytearray()
    diff_image = []

    # create diffrence array
    if len(img.shape) != 3:  # single-channel image
        num_of_channels = 1
        for y in range(img.shape[0]):
            for x in range(img.shape[1]):
                if x == 0:  # first pixel
                    diff_image.append(img[y][x])
                else:
                    diff_image.append(img[y][x] - img[y][x - 1])
    else:  # not single-channel image
        num_of_channels = img.shape[2]
        for y in range(img.shape[0]):
            for x in range(img.shape[1]):
                for c in range(img.shape[2]):  # include colour
                    if x == 0:  # first pixel
                        diff_image.append(img[y][x][c])
                    else:
                        diff_image.append(img[y][x][c] - img[y][x - 1][c])

    init_dict = {}  # initialize dictionary
    dict_size = (255 * 2)
    for i in range(dict_size + 1):
        init_dict[str(i - 255) +
                  ","] = i  # initialize all possible diffrences (no negative)
    dict_copy = init_dict.copy()
    sub_string = ""

    for element in diff_image:
        if dict_size >= 65536:  # if larger than max allowed size
            dict_copy = init_dict.copy()
            dict_size = (255 * 2)
        sub_string += str(element) + ","
        if not sub_string in dict_copy:
            dict_size += 1
            dict_copy[sub_string] = dict_size
            append_key = ",".join(sub_string.split(",")[:-2]) + ","
            byte_one = dict_copy[append_key] // (
                2**8)  # get first byte value (from int)
            byte_two = dict_copy[
                append_key] & 0b11111111  # get second byte value (from int)
            outputBytes.append(byte_one)
            outputBytes.append(byte_two)
            sub_string = str(element) + ","
    byte_one = dict_copy[sub_string] // (2**8)
    byte_two = dict_copy[sub_string] & 0b11111111
    outputBytes.append(byte_one)
    outputBytes.append(byte_two)

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.
    print num_of_channels
    outputFile.write('%s\n' % headerText)
    outputFile.write('%d %d %d\n' %
                     (img.shape[0], img.shape[1], num_of_channels))
    outputFile.write(outputBytes)

    # Print information about the compression

    if len(img.shape) == 3:
        inSize = img.shape[0] * img.shape[1] * img.shape[2]
        outSize = len(outputBytes)

        sys.stderr.write('Input size:         %d bytes\n' % inSize)
        sys.stderr.write('Output size:        %d bytes\n' % outSize)
        sys.stderr.write('Compression factor: %.2f\n' %
                         (inSize / float(outSize)))
        sys.stderr.write('Compression time:   %.2f seconds\n' %
                         (endTime - startTime))
    else:
        inSize = img.shape[0] * img.shape[1] * num_of_channels
        outSize = len(outputBytes)

        sys.stderr.write('Input size:         %d bytes\n' % inSize)
        sys.stderr.write('Output size:        %d bytes\n' % outSize)
        sys.stderr.write('Compression factor: %.2f\n' %
                         (inSize / float(outSize)))
        sys.stderr.write('Compression time:   %.2f seconds\n' %
                         (endTime - startTime))
Example #9
0
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()

    outputBytes = bytearray()

    index = 256
    # create initial dict for LZW compression containing all possible differences
    dictionary = dict((chr(i), i) for i in xrange(index))
    difs = []

    # loop through each channel of each pixel and compute the predictive difference
    for y in range(img.shape[0]):
        for x in range(1, img.shape[1]):
            for c in range(img.shape[2]):
                dif = 0
                if (img.shape[2] == 1):  # single channel
                    dif = abs(int(img[y, x]) - int(img[y, x - 1]))
                else:  # more channels
                    dif = abs(int(img[y, x, c]) - int(img[y, x - 1, c]))
                difs.append(dif)

    # for testing to check the similarity between uncompressed differences after decoding
    unencoded = open('unencoded.txt', 'w')
    for d in difs:
        unencoded.write(str(d) + '\n')
    unencoded.close()

    s = ''
    # loop through the differences and perform LZW compression
    for x in difs:
        sx = s + chr(x)
        if sx in dictionary:
            s = sx
        else:
            # turn index into 2 bytes
            b = struct.pack('H', dictionary[s])
            for byte in b:
                outputBytes.append(byte)
            # keep dictionary size below 65535 to enforce 2 byte indices
            if len(dictionary) < 65535:
                dictionary[sx] = index + 1
                index += 1
            s = chr(x)

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    outputFile.write('%s\n' % headerText)
    outputFile.write('%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2]))
    outputFile.write(outputBytes)

    # Print information about the compression

    inSize = img.shape[0] * img.shape[1] * img.shape[2]
    outSize = len(outputBytes)

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
Example #10
0
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()

    outputBytes = bytearray()

    baseDict = {}

    for i in range(512):
        baseDict[str(i)] = i

    pixelValues = []

    if (len(img.shape) == 2):
        channels = 1
        for x in range(img.shape[0]):
            for y in range(img.shape[1]):
                pixelValues.append(img[x, y])

    elif (len(img.shape) == 3):
        channels = 3
        for x in range(img.shape[0]):
            for y in range(img.shape[1]):
                for c in range(img.shape[2]):
                    pixelValues.append(img[x, y, c])
    else:
        print("invalid image format, exiting")
        quit()
    predictions = []
    predictions.append(pixelValues.pop(0) + 255)

    for i in pixelValues:
        predictions.append(int(pixelValues[i]) - int(pixelValues[i - 1]) + 255)

    numSymbols = img.shape[0] * img.shape[1] * channels
    nextIndex = len(baseDict)

    s = ""

    for i in range(numSymbols):
        x = str(predictions[i])

        if s + x in baseDict:
            s = s + x

        else:
            outputBytes.append((int(baseDict[s]) >> 8) & 0xFF)
            outputBytes.append(int(baseDict[s]) & 0xFF)

            baseDict[s + x] = nextIndex
            nextIndex += 1
            s = x

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    outputFile.write('%s\n' % headerText)
    if (channels == 1):
        outputFile.write('%d %d\n' % (img.shape[0], img.shape[1]))
    else:
        outputFile.write('%d %d %d\n' %
                         (img.shape[0], img.shape[1], img.shape[2]))
    outputFile.write(outputBytes)

    # Print information about the compression

    inSize = img.shape[0] * img.shape[1] * channels
    outSize = len(outputBytes)

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
Example #11
0
def compress(inputFile, outputFile):

    # Read the input file into a numpy array of 8-bit values
    #
    # The img.shape is a 3-type with rows,columns,channels, where
    # channels is the number of component in each pixel.  The img.dtype
    # is 'uint8', meaning that each component is an 8-bit unsigned
    # integer.

    img = netpbm.imread(inputFile).astype('uint8')

    # Compress the image
    #
    # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
    #
    # Note that single-channel images will have a 'shape' with only two
    # components: the y dimensions and the x dimension.  So you will
    # have to detect this and set the number of channels accordingly.
    # Furthermore, single-channel images must be indexed as img[y,x]
    # instead of img[y,x,1].  You'll need two pieces of similar code:
    # one piece for the single-channel case and one piece for the
    # multi-channel case.

    startTime = time.time()

    outputBytes = bytearray()

    # detect shape and set channels accordingly
    if len(img.shape) == 2:
        channels = [img.flatten()]
    elif len(img.shape) == 3:
        channels = [img[:, :, i].flatten() for i in range(img.shape[2])]

    # loop through each channel to encode each individually
    for chnl in channels:
        lzwD, i = initLZWD()

        #initialize counters to keep track of previous value and previous sequence for LZW
        prevP = 0
        prevS = ()
        for p in chnl:
            pDiff = p - prevP
            currS = prevS + (pDiff, )
            # if sequence not in dict, write to stream
            if currS not in lzwD:
                # stop at max 16 bit size -1 = 65535
                if i < 65535:
                    lzwD[currS] = i
                    i += 1
                # get value that was prevS
                val = lzwD[prevS]
                # encode into bytes
                smallB = val % 256
                bigB = val / 256
                # append bytes to output
                outputBytes.append(bigB)
                outputBytes.append(smallB)
                # reset prevS to new previous sequence
                prevS = (pDiff, )
            # sequence in dict, don't write new sequence, add to existing sequence
            else:
                # onto next sequence
                prevS = currS
            prevP = p
        # finish LZW by encoding end data
        if len(prevS) > 1:
            # same as 'if sequence not in dict'
            val = lzwD[prevS]
            smallB = val % 256
            bigB = val / 256
            outputBytes.append(bigB)
            outputBytes.append(smallB)

        # end flags
        outputBytes.append(255)
        outputBytes.append(255)

    endTime = time.time()

    # Output the bytes
    #
    # Include the 'headerText' to identify the type of file.  Include
    # the rows, columns, channels so that the image shape can be
    # reconstructed.

    outputFile.write('%s\n' % headerText)
    outputFile.write('%d %d %d\n' %
                     (img.shape[0], img.shape[1], len(channels)))
    outputFile.write(outputBytes)

    # Print information about the compression

    inSize = img.shape[0] * img.shape[1] * len(channels)
    outSize = len(outputBytes)

    sys.stderr.write('Input size:         %d bytes\n' % inSize)
    sys.stderr.write('Output size:        %d bytes\n' % outSize)
    sys.stderr.write('Compression factor: %.2f\n' % (inSize / float(outSize)))
    sys.stderr.write('Compression time:   %.2f seconds\n' %
                     (endTime - startTime))
Example #12
0
def compress( inputFile, outputFile ):

  # Read the input file into a numpy array of 8-bit values
  #
  # The img.shape is a 3-type with rows,columns,channels, where
  # channels is the number of component in each pixel.  The img.dtype
  # is 'uint8', meaning that each component is an 8-bit unsigned
  # integer.

  img = netpbm.imread( inputFile ).astype('uint8')

  # Compress the image
  #
  # REPLACE THIS WITH YOUR OWN CODE TO FILL THE 'outputBytes' ARRAY.
  startTime = time.time()
  dictionary = {} # create a dictionary
  dictsize = 0
  for i in range(-255, 256):
    dictionary[str(i)] = dictsize
    dictsize += 1

  channelsN = img.shape[2]
  outputlist = []
  outputBytes = bytearray()
  listSize = 0
  for y in range(img.shape[0]):
    for x in range(img.shape[1]):
      for c in range(channelsN):
        outputlist.append(img[y,x,c])
        listSize += 1
  print listSize, sys.getsizeof(outputlist)
  lastStr = ''
  current = outputlist[0]
  lastStr = str(int(current))
  for i in range(1, listSize):
    if dictsize >= 65536:
      dictionary = {} # create a dictionary
      dictsize = 0
      for i in range(-255, 256):
        dictionary[str(i)] = dictsize
        dictsize += 1

    current = outputlist[i]
    entry = lastStr+","+str(int(current))
    if entry in dictionary:
      lastStr = entry
    else:
      outBits = dictionary[lastStr]
      outLow = outBits & 0xFF
      outHigh = (outBits >> 8) & 0xFF
      outputBytes.append(outLow)
      outputBytes.append(outHigh)
      dictionary[entry] = dictsize
      dictsize += 1
      lastStr = str(int(current))

  if lastStr in dictionary:
    outBits = dictionary[lastStr]
    outLow = outBits & 0xFF
    outHigh = (outBits >> 8) & 0xFF
    outputBytes.append(outLow)
    outputBytes.append(outHigh)


  endTime = time.time()

  # Output the bytes
  #
  # Include the 'headerText' to identify the type of file.  Include
  # the rows, columns, channels so that the image shape can be
  # reconstructed.

  outputFile.write( '%s\n'       % headerText )
  outputFile.write( '%d %d %d\n' % (img.shape[0], img.shape[1], img.shape[2]) )
  outputFile.write( outputBytes )
  inSize  = img.shape[0] * img.shape[1] * img.shape[2]
  outSize = len(outputBytes)

  sys.stderr.write( 'Input size:         %d bytes\n' % inSize )
  sys.stderr.write( 'Output size:        %d bytes\n' % outSize )
  sys.stderr.write( 'Compression factor: %.2f\n' % (inSize/float(outSize)) )
  sys.stderr.write( 'Compression time:   %.2f seconds\n' % (endTime - startTime) )