From e35d76c4e72aab55241bc48c59a8b9765b7a1cff Mon Sep 17 00:00:00 2001 From: wolfycz1 <194477237+wolfycz1@users.noreply.github.com> Date: Sat, 22 Nov 2025 12:31:58 +0000 Subject: [PATCH] init --- script.py | 253 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 script.py diff --git a/script.py b/script.py new file mode 100644 index 0000000..3e885b3 --- /dev/null +++ b/script.py @@ -0,0 +1,253 @@ +# TENTO SKRIPT NENÍ URČEN PRO ŘEŠENÍ, SLOUŽÍ POUZE JAKO KONTROLA +# AUTOR SKRIPTU NERUČÍ ZA POUŽITÍ SKRIPTU ČI NESPRÁVNOST JEHO VÝSTUPU + +import os +from PIL import Image # PACKAGE 'pillow' REQUIRED + +color_map_types = { + "00": "soubor s obrázkem neobsahuje mapu barev", + "01": "je přítomna mapa barev" +} + +image_types = { + "00": "nejsou přítomna žádná obrazová data", + "01": "nekomprimovaný obraz s barevným mapováním", + "02": "nekomprimovaný obraz v True Color", + "03": "nekomprimovaný černobílý obraz (ve stupních šedi)" +} + +start_pixel_locations = { + "00": "Dole vlevo", + "01": "Nahoře vlevo", + "10": "Dole vpravo", + "11": "Nahoře vpravo" +} + +class Header: + COLOR_MAP_TYPE = 0 + IMAGE_TYPE = 1 + + MAP_START_INDEX = (2, 3+1) + MAP_SIZE = (4, 5+1) + MAP_OTHER = 6 + + WIDTH = (7, 8+1) + HEIGHT = (9, 10+1) + BITS_PER_PIXEL = 11 + + DESCRIPTOR = 12 + ALPHA_DEPTH = (0, 3+1) + START_PIXEL_LOCATION = (4, 5+1) + + DATA_OFFSET = 13 + +def raw2hex(input_raw: str) -> str: + if len(input_raw) % 2 != 0: + raise ValueError("Raw bajty nejsou v sudém počtu: " + input_raw) + + byte_list = [input_raw[j:j + 2] for j in range(0, len(input_raw), 2)] + + output_hex = ''.join(reversed(byte_list)) + + return output_hex + +def hex2dec(input_hex: str) -> str: + return str(int(input_hex, 16)) + +def hex2bin(input_hex: str) -> list[str]: + value = int(input_hex, 16) + bin_str = format(value, f'0{len(input_hex) * 4}b') + bin_arr = [str(bit) for bit in bin_str] + bin_arr.reverse() + return bin_arr + +def bin2dec(input_bin: str) -> str: + dec = int(input_bin.strip(), 2) + return str(dec) + +def hex2ascii(input_hex: str) -> str: + return bytes.fromhex(input_hex).decode("ascii") + +def hex2date(input_hex: str) -> str: + def read_field(start: int) -> int: + field_hex = input_hex[start:start + 4] + return int.from_bytes(bytes.fromhex(field_hex), byteorder="little") + + month = read_field(0) + day = read_field(4) + year = read_field(8) + hour = read_field(12) + minute = read_field(16) + second = read_field(20) + + return f"{day:02d}. {month:02d}. {year}, {hour:02d}:{minute:02d}:{second:02d}" + +def hex2ansi(input_hex: str) -> str: + if len(input_hex) != 6: + raise ValueError("Barvy raw bajtů nejsou ve skupinách 3 bajtů: " + input_hex) + + r = int(input_hex[0:2], 16) + g = int(input_hex[2:4], 16) + b = int(input_hex[4:6], 16) + + return f"\033[38;2;{r};{g};{b}m" + +def get_color_map_type(input_hex: str) -> str: + return color_map_types.get(input_hex, "vyhrazeno pro jiné účely") + +def get_image_type(input_hex: str) -> str: + return image_types.get(input_hex, "vyhrazeno pro jiné účely") + +def get_start_pixel_location(input_bin: str) -> str: + return start_pixel_locations.get(input_bin, "Neznámá lokace prvního pixel") + +def write_png(output_path, width, height, input_bytes, data_offset): + pixel_data = [] + for i in range(width * height): + base = data_offset + i * 3 + b = int(input_bytes[base + 0], 16) + g = int(input_bytes[base + 1], 16) + r = int(input_bytes[base + 2], 16) + pixel_data.extend([r, g, b]) + + pixel_bytes = bytes(pixel_data) + img = Image.frombytes("RGB", (width, height), pixel_bytes) + img.save(output_path) + print("Obrázek uložen do: " + output_path) + +choice = input("1: Zadat raw bajty (Doporuečno)\n2: Zadat název souboru s raw bajty\n3: Zadat název souboru .pif (papulastic-image-format)\n") + +input_bytes = [] +data = "" + +if choice == 1: + user_input = input("Zadjete raw bajty: ") + data = user_input.replace(" ", "") +elif choice == 2: + user_input = input("Cesta k souboru s raw batjy: ") + input_path = os.path.expanduser(user_input) + with open(input_path, "r") as f: + data = f.read().strip().replace(" ", "") +else: + user_input = input("Cesta k souboru .pif: ") + input_path = os.path.expanduser(user_input) + with open(input_path, "rb") as f: + raw_bytes = f.read().strip() + input_bytes = [f"{b:02x}" for b in raw_bytes] + +if choice == 1 or choice == 2: + for i in range(0, len(data), 2): + input_bytes.append(data[i:i + 2]) + +if len(input_bytes) > 0: + # COLOR MAP TYPE + color_map_type = input_bytes[Header.COLOR_MAP_TYPE] + print("Typ barevné mapy: " + get_color_map_type(raw2hex(color_map_type)) + " (0x" + raw2hex(color_map_type) + ")") + + # IMAGE TYPE + image_type = input_bytes[Header.IMAGE_TYPE] + print("Komprese a typ obrázku: " + get_image_type(raw2hex(image_type)) + " (0x" + raw2hex(image_type) + ")\n") + + # COLOR MAP SPECS + print("specifikace barevné palety: (Pokud je pole Color map type nastaveno na nulu (žádná mapa barev neexistuje), pak by těchto 5 bajtů mělo být nastaveno na nulu.)") + if color_map_type == "00": + print("Žádná mapa neexistuje, bajty by měly být nula") + else: + print("Mapa existuje") + + # MAP START INDEX + start, end = Header.MAP_START_INDEX + map_start_index = "".join(input_bytes[start:end]) + print("\tIndex první položky barevné mapy: " + hex2dec(raw2hex(map_start_index)) + " (0x" + raw2hex(map_start_index) + ")") + + # MAP SIZE + start, end = Header.MAP_SIZE + map_size = "".join(input_bytes[start:end]) + print("\tDélka barevné mapy: " + hex2dec(raw2hex(map_size)) + " (0x" + raw2hex(map_size) + ")") + + # MAP OTHER + map_other = input_bytes[Header.MAP_OTHER] + print("\tDoplňkové údaje k barevné mapě: Není definováno (0x" + raw2hex(map_other) + ")\n") + + # IMAGE SPECS + print("Specifikace rozměrů obrázku:") + + # WIDTH + start, end = Header.WIDTH + width = "".join(input_bytes[start:end]) + print("\tŠířka obrázku v pixelech: " + hex2dec(raw2hex(width)) + "px (0x" + raw2hex(width) + ")") + + # HEIGHT + start, end = Header.HEIGHT + height = "".join(input_bytes[start:end]) + print("\tVýška obrázku v pixelech: " + hex2dec(raw2hex(height)) + "px (0x" + raw2hex(height) + ")") + + size = int(hex2dec(raw2hex(width))) * int(hex2dec(raw2hex(height))) + + # BITS/PIXEL + bits_per_pixel = input_bytes[Header.BITS_PER_PIXEL] + print("\tHloubka pixelu (bity na pixel): " + hex2dec(raw2hex(bits_per_pixel)) + " bitů na pixel (0x" + raw2hex(bits_per_pixel) + ")") + + # DESCRIPTOR + descriptor_bits = hex2bin(raw2hex(input_bytes[Header.DESCRIPTOR])) + print("\tDeskriptor obrazu: (0b" + "".join(descriptor_bits) + ")") + + # ALPHA DEPTH + start, end = Header.ALPHA_DEPTH + alpha_depth = "".join(descriptor_bits[start:end]) + print("\t\tHloubka alfa kanálu: " + bin2dec(alpha_depth) + " (0b" + alpha_depth + ")") + + # START PIXEL LOCATION + start, end = Header.START_PIXEL_LOCATION + start_pixel_location = "".join(descriptor_bits[start:end]) + print("\t\tPočátek obrazu (kde leží první pixel): " + get_start_pixel_location(start_pixel_location) + " (0b" + start_pixel_location + ")") + + # UNUSED + print("\t\tBity 6 a 7 nejsou definovány") + + # DATA + choice = input("1: Vypsat data do konzole (Doporučeno pouze pro malé obrázky)\n2: Uložit obrázek do PNG souboru\n") + + if choice == 1: + print("Data:") + data = "" + for i in range(0, int(hex2dec(raw2hex(height)))): + for j in range(0, int(hex2dec(raw2hex(width)))): + byte_list = input_bytes[Header.DATA_OFFSET + (i * width + j) * 3 : Header.DATA_OFFSET + (i * width + j) * 3 + 3] + data += hex2ansi(raw2hex("".join(byte_list))) + data += "#" + raw2hex("".join(byte_list)) + " \033[0m" + data += "\n" + + print(data) + else: + user_input = input("Zadejte cestu pro výsledný soubor PNG obrázku: ") + output_path = os.path.expanduser(user_input) + write_png(output_path, int(hex2dec(raw2hex(width))), int(hex2dec(raw2hex(height))), input_bytes, Header.DATA_OFFSET) + + offset = Header.DATA_OFFSET + size * 3 + # OTHER DATA + print("Rozšiřující data:") + # INITIALS + start, end = (offset, offset + 2) + + print("\tIniciály autora: " + hex2ascii("".join(input_bytes[start:end])) + " (0x" + "".join(input_bytes[start:end]) + ")") + + # DATE + start, end = (offset + 3, offset + 15) + date = input_bytes[start:end] + print("\t\033[31mDatum (čas pořízení): " + hex2date("".join(input_bytes[start:end])) + " (0b" + "".join(date) + ")\033[0m\n") + + # FOOTER + print("Patička:") + # SIGNATURE + start, end = (offset + 15, offset + 31) + signature = input_bytes[start:end] + print("\t\033[31mPodpis: " + hex2ascii("".join(signature)) + " (0x" + "".join(signature) + ")\033[0m") + # ALWAYS DOT + always_dot = input_bytes[end] + print("\tRezervovaný znak: " + hex2ascii(always_dot) + " (0x" + always_dot + ")") + + always_zero = input_bytes[end + 1] + print("\tBinární nula: 0x" + always_zero) + + print("\n\nDůležité informace zaznačeny barevně") \ No newline at end of file