Files
SDR-Rover/Projects/SDR_Rover/tests/lab007_image_fragmentation.py
LittleSam129 acf7a76546 initial commit
2026-07-20 13:58:58 +03:00

270 lines
5.9 KiB
Python

"""
Lab007. Разбиение JPEG на фрагменты и обратная сборка.
Этапы:
1. Создание тестового JPEG.
2. Чтение файла как последовательности байтов.
3. Разбиение изображения на фрагменты.
4. Формирование цифрового пакета для каждого фрагмента.
5. Перемешивание порядка доставки пакетов.
6. Проверка CRC и разбор пакетов.
7. Обратная сборка изображения.
8. Сравнение контрольных сумм файлов.
"""
from hashlib import sha256
from pathlib import Path
import random
from PIL import Image
from protocol.image_fragments import (
decode_image_fragment,
encode_image_fragment,
reassemble_image,
split_image_bytes,
)
from protocol.packet import (
MESSAGE_TYPE_IMAGE_FRAGMENT,
build_packet,
parse_packet,
)
# ============================================================
# Настройки
# ============================================================
IMAGE_WIDTH = 320
IMAGE_HEIGHT = 240
IMAGE_ID = 20260713
FRAGMENT_DATA_SIZE = 512
random_generator = random.Random(2026)
# ============================================================
# Пути к файлам
# ============================================================
source_directory = Path("data/raw")
received_directory = Path("data/received")
source_directory.mkdir(
parents=True,
exist_ok=True,
)
received_directory.mkdir(
parents=True,
exist_ok=True,
)
source_path = (
source_directory
/ "lab007_source.jpg"
)
received_path = (
received_directory
/ "lab007_reassembled.jpg"
)
# ============================================================
# Создание тестового JPEG
# ============================================================
image = Image.new(
"RGB",
(IMAGE_WIDTH, IMAGE_HEIGHT),
)
pixels = image.load()
for y in range(IMAGE_HEIGHT):
for x in range(IMAGE_WIDTH):
red = (
x * 255
// (IMAGE_WIDTH - 1)
)
green = (
y * 255
// (IMAGE_HEIGHT - 1)
)
blue = (
(x + y) * 255
// (
IMAGE_WIDTH
+ IMAGE_HEIGHT
- 2
)
)
pixels[x, y] = (
red,
green,
blue,
)
image.save(
source_path,
format="JPEG",
quality=60,
optimize=True,
)
# ============================================================
# Чтение изображения
# ============================================================
source_bytes = source_path.read_bytes()
source_hash = sha256(
source_bytes
).hexdigest()
# ============================================================
# Разбиение изображения на фрагменты
# ============================================================
fragments = split_image_bytes(
image_bytes=source_bytes,
image_id=IMAGE_ID,
fragment_data_size=FRAGMENT_DATA_SIZE,
)
# ============================================================
# Формирование цифровых пакетов
# ============================================================
packets = []
for fragment in fragments:
fragment_payload = encode_image_fragment(
fragment
)
packet = build_packet(
payload=fragment_payload,
message_type=MESSAGE_TYPE_IMAGE_FRAGMENT,
sequence_number=fragment.fragment_index,
)
packets.append(packet)
# ============================================================
# Имитация доставки в произвольном порядке
# ============================================================
random_generator.shuffle(packets)
received_fragments = []
for packet in packets:
parsed_packet = parse_packet(packet)
assert (
parsed_packet.message_type
== MESSAGE_TYPE_IMAGE_FRAGMENT
)
fragment = decode_image_fragment(
parsed_packet.payload
)
assert (
parsed_packet.sequence_number
== fragment.fragment_index
)
received_fragments.append(fragment)
# ============================================================
# Сборка изображения
# ============================================================
received_bytes = reassemble_image(
received_fragments
)
received_path.write_bytes(
received_bytes
)
received_hash = sha256(
received_bytes
).hexdigest()
# ============================================================
# Проверки
# ============================================================
assert received_bytes == source_bytes
assert received_hash == source_hash
with Image.open(received_path) as received_image:
received_image.verify()
# ============================================================
# Результаты
# ============================================================
print("=== Lab007. Фрагментация изображения ===")
print("\nИсходный файл:")
print(source_path)
print("\nВосстановленный файл:")
print(received_path)
print("\nРазмер изображения:")
print(
IMAGE_WIDTH,
"x",
IMAGE_HEIGHT,
"пикселей",
)
print("\nРазмер JPEG:")
print(
len(source_bytes),
"байт",
)
print("\nРазмер данных одного фрагмента:")
print(
FRAGMENT_DATA_SIZE,
"байт",
)
print("\nКоличество фрагментов:")
print(
len(fragments)
)
print("\nSHA-256 исходного файла:")
print(source_hash)
print("\nSHA-256 восстановленного файла:")
print(received_hash)
print(
"\nПроверка пройдена: "
"JPEG восстановлен байт в байт."
)