the method compresses the data using run-length encoding and returns bytearray containing the packed data where bitarray is like list of ones and zerosa bytearray is like list of byte objects (each byteof coursecontaining ones or zerosthe algorithm that performs the compression is pretty simple (although ' like to point out that it took me two days to implement and debug it simple to understand does not necessarily imply easy to write!it first sets the last variable to the type of bit in the current run (either true or falseit then loops over the bitscounting each oneuntil it finds one that is different when it doesit constructs new byte by making the leftmost bit of the byte (the positioneither zero or onedepending on what the last variable contained then it resets the counter and repeats the operation once the loop is doneit creates one last byte for the last runand returns the result while we're creating building blockslet' make function that compresses row of image datadef compress_row(row)compressed bytearray(chunks split_bits(row for chunk in chunkscompressed extend(compress_chunk(chunk)return compressed this function accepts bitarray named row it splits it into chunks that are each bits wide using function that we'll define very shortly then it compresses each of those chunks using the previously defined compress_chunkconcatenating the results into bytearraywhich it returns we define split_bits as simple generatordef split_bits(bitswidth)for in range( len(bits)width)yield bits[ : +widthnowsince we aren' certain yet whether this will run more effectively in threads or processeslet' wrap these functions in method that runs everything in provided executordef compress_in_executor(executorbitswidth)row_compressors [for row in split_bits(bitswidth)compressor executor submit(compress_rowrow