from __future__ import annotations from dataclasses import dataclass import numpy as np from entities.block_grid8 import BlockGrid8 from entities.lsb_row8 import LsbRow8 from entities.label64 import Label64 from entities.sequence8 import Sequence8 @dataclass(frozen=True) class Embedder: """Встраивание метки в 2D-компоненту Y/Cb/Cr через LSB верхней строки блоков 8×8.""" def embed_component(self, component: np.ndarray, label: Label64, seq: Sequence8) -> np.ndarray: """Вернуть новую компоненту с вшитой меткой.""" if component.ndim != 2: raise ValueError("Ожидается 2D-компонента.") h, w = component.shape if h % 8 != 0 or w % 8 != 0: raise ValueError("Размеры компоненты должны быть кратны 8.") blocks = BlockGrid8.split(component) bits = label.to_vector() # 4096 if blocks.shape[0] != bits.size: raise ValueError("Количество блоков должно равняться 4096.") out_blocks = blocks.copy() # Для каждого бита берём 8-битную сигнатуру и встраиваем в верхнюю строку блока for i in range(bits.size): pattern = seq.for_bit(int(bits[i])) out_blocks[i] = LsbRow8.embed(out_blocks[i], pattern) return BlockGrid8.merge(out_blocks, h, w)