Esempio n. 1
0
    def test_with_large_strings(self):
        test_sizes = [1000, 10000, 100000]

        for size in test_sizes:
            contents = random_string(size).encode('ascii')
            decompressed = heatshrink.decompress(heatshrink.compress(contents))
            self.assertEqual(decompressed, contents)
Esempio n. 2
0
 def compress(self):
     if self.flag("COMPRESS"):
         print("WARN: Image already compressed!")
         return
     uncompressed_length = self.file_size - self.get_header_length()
     self.fd.seek(self.get_header_length(), os.SEEK_SET)
     data = self.fd.read(uncompressed_length)
     data = heatshrink2.compress(data, window_sz2=11, lookahead_sz2=4)
     self.fd.seek(self.get_header_length(), os.SEEK_SET)
     self.fd.truncate(self.get_header_length())
     self.fd.write(data)
     self.flag("COMPRESS", True)
     self.read_file_size()
Esempio n. 3
0
 def setUp(self):
     self.compressed = heatshrink.compress(b'abcde')
Esempio n. 4
0
 def test_round_trip(self):
     compressed = heatshrink.compress(b'a string')
     self.assertEqual(heatshrink.decompress(compressed), b'a string')
Esempio n. 5
0
 def test_with_a_paragraph(self):
     compressed = heatshrink.compress(TEXT)
     self.assertEqual(heatshrink.decompress(compressed), TEXT)
Esempio n. 6
0
 def test_different_params_yield_different_output(self):
     string = b'A string with stuff in it'
     self.assertNotEqual(heatshrink.compress(string, window_sz2=8),
                         heatshrink.compress(string, window_sz2=11))
     self.assertNotEqual(heatshrink.compress(string, lookahead_sz2=4),
                         heatshrink.compress(string, lookahead_sz2=8))
Esempio n. 7
0
 def test_compress_with_lookahead_sz2(self):
     compressed = heatshrink.compress(b'abcde', lookahead_sz2=3)
     self.assertEqual(compressed, b'\xb0\xd8\xacvK(')
Esempio n. 8
0
 def test_compress_with_window_sz2(self):
     compressed = heatshrink.compress(b'abcde', window_sz2=8)
     # FIXME: Prove that this setting changes output
     self.assertEqual(compressed, b'\xb0\xd8\xacvK(')
Esempio n. 9
0
def add_file(config, root, filename, actions):
    filepath = os.path.join(root, filename)
    with open(filepath, 'rb') as f:
        initial_data = f.read()

    processed_data = initial_data

    for action in actions:
        if action in ['gzip', 'heatshrink']:
            pass
        elif action in config['tools']:
            tool = config['tools'][action]
            command = tool['command']
            p = subprocess.Popen(command,
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 shell=True)
            processed_data = p.communicate(input=processed_data)[0]
        else:
            print(f'Unknown action: {action}', file=sys.stderr)
            sys.exit(1)

    flags = 0
    if 'gzip' in actions:
        flags |= FLAG_GZIP
        tool = config['tools']['gzip']
        level = min(max(tool.get('level', 9), 0), 9)
        processed_data = gzip.compress(processed_data, level)

    if 'heatshrink' in actions:
        compression = COMPRESS_HEATSHRINK
        tool = config['tools']['heatshrink']
        level = min(max(tool.get('level', 9), 0), 9) // 2
        window_sizes, lookahead_sizes = [5, 6, 8, 11, 13], [3, 3, 4, 4, 4]
        window_sz2, lookahead_sz2 = window_sizes[level], lookahead_sizes[level]
        header = bytes([window_sz2 << 4 | lookahead_sz2])
        compressed_data = header + heatshrink2.compress(
            processed_data, window_sz2=window_sz2, lookahead_sz2=lookahead_sz2)
    else:
        compression = COMPRESS_NONE
        compressed_data = processed_data

    if len(compressed_data) >= len(processed_data):
        compression = COMPRESS_NONE
        compressed_data = processed_data

    initial_len, processed_len, compressed_len = len(initial_data), len(
        processed_data), len(compressed_data)

    if initial_len < 1024:
        initial = f'{initial_len} B'
        compressed = f'{compressed_len} B'
    elif initial_len < 1024 * 1024:
        initial = f'{initial_len / 1024:.1f} KiB'
        compressed = f'{compressed_len / 1024:.1f} KiB'
    elif initial_len < 1024 * 1024 * 1024:
        initial = f'{initial_len / 1024 / 1024:.1f} MiB'
        compressed = f'{compressed_len / 1024 / 1024:.1f} MiB'

    percent = 100.0
    if initial_len > 0:
        percent = compressed_len / initial_len * 100

    filename = filename.replace('\\', '/')
    print(f'{filename}: {initial} -> {compressed} ({percent:.1f}%)')
    filename = filename.encode('utf8')
    filename = filename.ljust((len(filename) + 4) // 4 * 4, b'\0')
    compressed_data = compressed_data.ljust((compressed_len + 3) // 4 * 4,
                                            b'\0')

    header = header_struct.pack(ESPFS_MAGIC, flags, compression, len(filename),
                                compressed_len, processed_len)
    return header + filename + compressed_data
Esempio n. 10
0
def make_file_object(hash, path, data, attributes):
    global config

    index = attributes['index']
    actions = attributes['actions']
    flags = 0
    compression = ESPFS_COMPRESSION_NONE
    initial_data = data
    initial_len = len(data)

    if 'cache' in actions:
        flags |= ESPFS_FLAG_CACHE

    for action in actions:
        if action in config['preprocessors']:
            command = config['preprocessors'][action]['command']
            process = subprocess.Popen(command,
                                       stdin=subprocess.PIPE,
                                       stdout=subprocess.PIPE,
                                       shell=True)
            data = process.communicate(input=data)[0]

    file_data = data
    file_len = len(data)

    if file_len >= initial_len:
        data = initial_data
        file_len = initial_len

    if 'gzip' in actions:
        flags |= ESPFS_FLAG_GZIP
        level = config['compressors']['gzip']['level']
        level = min(max(level, 0), 9)
        data = gzip.compress(data, level)
    elif 'heatshrink' in actions:
        compression = ESPFS_COMPRESSION_HEATSHRINK
        window_sz2 = config['compressors']['heatshrink']['window_sz2']
        lookahead_sz2 = config['compressors']['heatshrink']['lookahead_sz2']
        data = espfs_heatshrink_header_t.pack(
            window_sz2, lookahead_sz2, 0) + heatshrink2.compress(
                data, window_sz2=window_sz2, lookahead_sz2=lookahead_sz2)

    data_len = len(data)

    if data_len >= file_len:
        flags &= ~ESPFS_FLAG_GZIP
        compression = ESPFS_COMPRESSION_NONE
        data = file_data
        data_len = file_len

    if initial_len < 1024:
        initial_len_str = '%d B' % (initial_len)
        data_len_str = '%d B' % (data_len)
    elif initial_len < 1024 * 1024:
        initial_len_str = '%.1f KiB' % (initial_len / 1024)
        data_len_str = '%.1f KiB' % (data_len / 1024)
    else:
        initial_len_str = '%.1f MiB' % (initial_len / 1024 / 1024)
        data_len_str = '%.1f MiB' % (data_len / 1024 / 1024)

    percent = 100.0
    if initial_len > 0:
        percent = data_len / initial_len * 100.0

    stats = '%-9s -> %-9s (%.1f%%)' % (initial_len_str, data_len_str, percent)
    print('%08x %-34s file %s' % (hash, path, stats))

    path = path.encode('utf8') + b'\0'
    path = path.ljust((len(path) + 3) // 4 * 4, b'\0')
    data = data.ljust((data_len + 3) // 4 * 4, b'\0')
    header = espfs_object_header_t.pack(
        ESPFS_TYPE_FILE, espfs_object_header_t.size + espfs_file_header_t.size,
        index, len(path), 0) + espfs_file_header_t.pack(
            data_len, file_len, flags, compression, 0)

    return header + path + data