pc15codec¶
Step 3 - Payload ANS0 (rANS)¶
Format: payload = b"ANS0" + u8 L + table_id[:L] + rANS_stream_bytes
Tables gelées: pc15codec.rans.DEFAULT_TABLE_ID = "v15_default"
Override: PC15_RANS_TABLES=/abs/path/with/json
API:
from pc15codec.payload import ANS0_FMT, encode_tile_payload, decode_tile_payload
fmt, blob = encode_tile_payload(gen_id, qv_id, seed, flags, offsets, table_id="v15_default")
g,qv,seed,flags,offs = decode_tile_payload(blob)
Critères d’acceptation (Step 3)¶
write_stream_v15/read_stream_v15
inchangés (déjà OK). :contentReference[oaicite:10]{index=10}- Les
.pc15
produits contiennent desTileRec.payload_fmt == 0 (ANS0)
et se décodent sans erreur (round-trip symbolique). encode_tile_payload
/decode_tile_payload
CPU-only OK.- Tables gelées chargées via
load_table_by_id("v15_default")
. :contentReference[oaicite:11]{index=11} - Back-compat :
PC15_PAYLOAD_FMT=RAW
→ chemin actuel RAW inchangé. :contentReference[oaicite:12]{index=12}
Step 4 - Reconstruction & RD minimal¶
But : décoder les symboles ANS0 → (gen_id, qv_id, seed, flags, offsets) → déquantifier les paramètres → rendre la tuile (proc) → blender dans le canvas Y. Côté encodage, une recherche coarse sélectionne par tuile le meilleur candidat au score RD.
Pipeline¶
Encode (par tuile)
1. Génère un petit set de candidats (générateur + params “coarse”).
2. dist = α·(1-SSIM) + (1-α)·MSE_norm
sur la tuile de référence.
3. bits
estimés via tables rANS gelées (ou “exact” par encodage réel).
4. Score RD = dist + λ·bits
; garde le meilleur.
5. quantize_params
→ (qv_id, offsets)
; pack_symbols
; encode_tile_payload
(ANS0).
Decode (par tuile)
1. decode_tile_payload
(lit b"ANS0"|L|table_id|stream
).
2. dequantize_params(qv_id, offsets)
→ params
.
3. pc15proc.render(gen_name, h, w, params)
→ tuile synthèse.
4. Blend Hann sur l’overlap → canvas final Y [1,1,H,W]
.
Critères d’acceptation - Step 4¶
decode_y
reconstruit une image non nulle (plus de noir).encode_y
effectue une recherche minimale et choisit le meilleur score RD (coarse → pas encore de refine/beam).- Déterminisme : deux encodes strictement identiques (mêmes cfg/seed/image) produisent exactement les mêmes bytes.
estimate_bits_from_table
(mode table) est proche des bits exact (mode exact) : tolérance ±8 bits ou ±5 %.- QV :
quantize_params
/dequantize_params
opèrent et conservent l’échelle globale des paramètres. - Compat v15 : framing inchangé (header/records/stream). Seuls les payloads passent en ANS0.
Variables d’environnement utiles¶
Var | Valeurs | Rôle |
---|---|---|
PC15_PAYLOAD_FMT |
ANS0 | RAW |
Choix du format de payload (ANS0 par défaut ; RAW pour debug). |
PC15_SCORE_BITS |
table | exact |
Estimation des bits (rapide vs encodage réel rANS). |
PC15_RANS_TABLES |
chemin | Répertoire custom pour les tables rANS gelées (*.json ). |
PC15_GENS_JSON |
chemin | (Optionnel) Override du mapping gen_id ↔ gen_name . |
PC15_ALLOW_CPU_TESTS |
1 |
Force des chemins CPU-friendly (utile sans GPU). |
Extrait d’usage¶
import torch
from pc15codec import CodecConfig, DEFAULT_TABLE_ID
from pc15codec.codec import encode_y, decode_y
# Image Y en [-1,1] (ex. rampe synthétique)
H, W = 256, 256
y = torch.linspace(-1, 1, steps=H).view(1,1,H,1) * torch.ones(1,1,1,W)
cfg = CodecConfig(
tile=64, overlap=16, seed=2025,
lambda_rd=0.015, alpha_mix=0.7,
rans_table_id=DEFAULT_TABLE_ID
)
enc = encode_y(y, cfg) # -> {"bitstream", "bpp", "stats", ...}
yhat = decode_y(enc["bitstream"]) # -> torch.Tensor [1,1,H,W]
# Déterminisme (mêmes bytes)
enc2 = encode_y(y, cfg)
assert enc2["bitstream"] == enc["bitstream"]
Codec (encode / decode)¶
RAW_FMT = 1
module-attribute
¶
ANS0_FMT = 0
module-attribute
¶
DEFAULT_TABLE_ID = 'v15_default'
module-attribute
¶
__all__ = ['CodecConfig', 'encode_y', 'decode_y']
module-attribute
¶
CodecConfig
dataclass
¶
Configuration publique et stable du codec PC15 v15 (Step 3 - Y-only).
Cette config est consommée par pc15codec.codec.encode_y/decode_y
.
Elle couvre :
- le tiling (taille/overlap),
- quelques flags de framing,
- les paramètres RD (utiles aux steps suivants),
- le seed de déterminisme (dérivé par tuile à l'encodage),
- l'identifiant de tables rANS gelées.
Champs
tile : int, default=256
Taille (carrée) des tuiles en pixels. Doit être > 0.
overlap : int, default=24
Overlap en pixels (blend inter-tuiles). Doit vérifier 0 <= overlap < tile.
colorspace : int, default=0
Espace couleur. 0 = Y-only (Step 3). Chroma viendra plus tard.
flags : int, default=0
Champs de bits réservés pour le framing/compat.
payload_precision : int, default=12
Précision des tables si génération à la volée (u16). Conservé pour la méta.
lambda_rd : float, default=0.015
Poids du coût bits (λ) dans l’objectif RD (steps suivants).
alpha_mix : float, default=0.7
Mélange SSIM/MSE dans la distortion (steps suivants).
seed : int, default=1234
Graine globale. La graine par tuile est dérivée de celle-ci pour garantir
l’idempotence (mêmes cfg ⇒ mêmes bytes).
rans_table_id : str, default="v15_default"
Identifiant de tables rANS gelées. Doit correspondre à un JSON chargeable via
pc15codec.rans.load_table_by_id(...)
. Peut être surchargé via l’ENV
PC15_RANS_TABLES
pour pointer un répertoire custom.
ai : object | None, default=None
Réservé pour des aides “learning-based” futures. # [ML]
Notes
- La dataclass est immuable (
frozen=True
) pour faciliter le hashing et l’idempotence des runs. - Aucune conversion n’est appliquée : les validations lèvent une
ValueError
si les bornes sont violées.
tile = 256
class-attribute
instance-attribute
¶
overlap = 24
class-attribute
instance-attribute
¶
colorspace = 0
class-attribute
instance-attribute
¶
flags = 0
class-attribute
instance-attribute
¶
payload_precision = 12
class-attribute
instance-attribute
¶
lambda_rd = 0.015
class-attribute
instance-attribute
¶
alpha_mix = 0.7
class-attribute
instance-attribute
¶
seed = 1234
class-attribute
instance-attribute
¶
rans_table_id = 'v15_default'
class-attribute
instance-attribute
¶
ai = None
class-attribute
instance-attribute
¶
TileRec
dataclass
¶
Enregistrement de tuile (Step 1, version simple). Note: pas encore d'encodage rANS ici (payload=b"" possible).
tile_id
instance-attribute
¶
gen_id
instance-attribute
¶
qv_id
instance-attribute
¶
seed
instance-attribute
¶
rec_flags = 0
class-attribute
instance-attribute
¶
payload_fmt = 0
class-attribute
instance-attribute
¶
payload = field(default_factory=bytes)
class-attribute
instance-attribute
¶
to_dict()
¶
from_dict(d)
staticmethod
¶
TileGridCfg
dataclass
¶
SearchCfg
dataclass
¶
Configuration de scoring RD.
- lambda_rd : poids du terme "bits" (R) dans RD = D + lambda_rd * R
- metric : "ssim" (par défaut), "mse", ou "mixed" (pondère SSIM/MSE via alpha)
- alpha : poids de SSIM dans le mode "mixed" (D = alpha(1-ssim) + (1-alpha)MSE)
- beam_k : réservé pour beam-search (non utilisé ici)
- early_exit_tau : seuil d'early exit (non utilisé ici)
read_stream_v15(buf)
¶
Sépare et décode header v15 + bloc records v15 depuis un flux binaire unique.
write_stream_v15(header_dict, records)
¶
Concatène header v15 (pack_v15) + bloc records v15 (pack_records_v15).
encode_tile_payload_raw(data)
¶
Encode RAW → (fmt, payload)
pour debug/compatibilité.
Paramètres
data : bytes Octets à passer tels quels.
Retour
(fmt, payload) : (int, bytes)
- fmt == RAW_FMT
(1)
- payload == data
(copie immuable)
Remarque
Ce mode bypass l’entropie et ne doit pas être utilisé en production.
decode_tile_payload_raw(fmt, payload)
¶
Décode (fmt, payload)
lorsque fmt == RAW_FMT
.
Paramètres
fmt : int
Doit valoir RAW_FMT
(1).
payload : bytes
Octets encodés précédemment en mode RAW.
Retour
bytes Les octets d’origine.
Exceptions
ValueError si fmt != RAW_FMT
.
TypeError si payload
n’est pas un buffer d’octets.
encode_tile_payload(gen_id, qv_id, seed, flags, offsets, table_id=DEFAULT_TABLE_ID)
¶
Encode les symboles de tuile en payload ANS0 (rANS).
Paramètres
gen_id : int
Identifiant du générateur procédural sélectionné pour la tuile.
qv_id : int
Identifiant de la quantification vectorielle (codebook/entrée).
seed : int
Graine (seed) déterministe pour la synthèse de la tuile.
flags : int
Bits d’options/état pour la tuile.
offsets : List[int]
Offsets fins et/ou paramètres additionnels (liste bornée par pack_symbols
).
table_id : str, par défaut DEFAULT_TABLE_ID
Identifiant de tables rANS gelées à utiliser (ex: "v15_default").
Retour
(fmt, payload) : (int, bytes)
- fmt == ANS0_FMT
(0)
- payload
commence par b"ANS0"
puis contient table_id
et le flux rANS.
Détails
- Les champs
(gen_id, qv_id, seed, flags, offsets)
sont packés en une suite de symboles 0..255 viapack_symbols(...)
. - La liste de symboles est compressée via rANS avec les tables référencées
par
table_id
. L’en-tête ANS0 est automatiquement préfixé parrans_encode
.
Exceptions
TypeError / ValueError si les types/tailles sortent des bornes définies par
pack_symbols
ou si table_id
est invalide.
decode_tile_payload(payload)
¶
Décode un payload ANS0 (rANS) vers les symboles de tuile.
Paramètres
payload : bytes
Flux produit par encode_tile_payload(...)
(entête b"ANS0" attendu).
Retour
(gen_id, qv_id, seed, flags, offsets) : Tuple[int, int, int, int, List[int]]
Détails
rans_decode
vérifie l’entêteANS0
, littable_id
, charge les tables, puis reconstruit la liste de symboles 0..255.unpack_symbols
reconstitue la 5-uplet(gen_id, qv_id, seed, flags, offsets)
.
Exceptions
ValueError si l’entête est invalide ou si le stream est corrompu.
pack_symbols(gen_id, qv_id, seed, flags, offsets)
¶
load_table_by_id(table_id, paths=None)
¶
Charge une table rANS gelée par son identifiant et la convertit vers le format canonique attendu par rans_impl.
Ordre de résolution (du plus prioritaire au moins prioritaire) :
0) ENV PC15_RANS_TABLES
→ pc15codec/data/rans/<table_id>.json
Caching : - Résultat mis en cache mémoire selon la clé (env_root, models_root, table_id) pour éviter des I/O répétées (après coercition). - Changer d’ENV ou de models dir invalide implicitement la clé.
Exceptions
FileNotFoundError si aucune source ne fournit table_id
.
ValueError si le contenu JSON est invalide ou non convertible.
tile_image(y, grid)
¶
Prépare la grille de tuiles pour une image Y [1,1,H,W].
blend(tiles, spec, H, W, window='hann', window_params=None, eps=1e-08)
¶
Assemble des tuiles [N,1,size,size] en une image [1,1,H,W] avec blend normalisé.
- window: 'hann' (defaut) | 'tukey' | 'kaiser'
- window_params:
- 'tukey': {'alpha': float in [0,1]} par défaut alpha=2*overlap/size clampé
- 'kaiser': {'beta': float} par défaut 6.5
score_batch_bits(y_tile, synth, cfg, *, bits_est=None, bits=None, seam_weight=0.0, border_mask=None)
¶
Variante où le coût "bits" (R) est fourni par l'appelant, shape (B,).
Compat :
- bits_est=
(ancien nom utilisé par certains tests)
- bits=
(nom recommandé)
- D: même calcul que score_batch (SSIM/MSE/mixed + couture optionnelle)
- R: = bits fournis
- RD: D + lambda_rd * R
estimate_bits_from_table(symbols, table)
¶
Estimation table-based des bits de symbols
:
R ≈ ∑_t -log2( counts[s]/base ), base = ∑ counts
Compatible avec les tables gelées ANS0 (clés usuelles: "counts", "precision"
ou "alphabet_size"). Si precision
est absent, on déduit base
= sum(counts).
_payload_mode_from_env()
¶
Lit le mode payload (ENV PC15_PAYLOAD_FMT
).
- "RAW" → payloads bruts (debug / compat)
- sinon → "ANS0" (défaut), i.e., rANS avec tables gelées référencées.
_bits_mode_from_env()
¶
Lit le mode d'estimation des bits (ENV PC15_SCORE_BITS
).
- "exact" → bits exact via encodage rANS (coûteux si beaucoup de candidats)
- sinon → "table" (défaut) : somme des -log2(p) à partir de la table gelée
_tile_seed(global_seed, tile_id)
¶
Mélange déterministe pour produire une seed par tuile dans [0..2^32-1].
Formule: splitmix-like (petit hash 32-bit suffisant ici).
_synth_stripes(H, W, *, freq, ang_deg, phase_deg, device='cpu', dtype=torch.float32)
¶
Tuile synthétique déterministe type “stripes” en [-1,1], shape [1,1,H,W].
Paramètres discrets : - freq ∈ Z+ (densité de bandes) - ang_deg ∈ [0..179] - phase_deg ∈ [0..359] (ici on l’utilise en degrés, remappé en radians)
_synth_from_seed(H, W, *, seed, device='cpu', dtype=torch.float32)
¶
Variante sans paramètres explicites (utilisée pour la recon Step 4 “non nulle”). On déduit (freq,angle,phase) simples depuis la seed pour varier légèrement.
encode_y(img_y, cfg)
¶
Encode un plan Y en flux v15 avec recherche coarse RD par tuile + payload ANS0.
Comportement
- Par tuile:
1) on forme une petite grille de candidats (stripes : freq×angle×phase),
2) on synthétise le batch [B,1,s,s] (CPU),
3) on calcule la distorsion D (metric SearchCfg ; défaut "ssim"),
4) on estime le coût bits R par candidat (ENV
PC15_SCORE_BITS
: "exact" ou "table"), 5) on scoreRD = D + λ·R
et on choisit le meilleur, 6) on quantize les paramètres en offsets discrets (petits indices), 7) on emballe en ANS0 viaencode_tile_payload(...)
. - Le framing v15 (header/records) est inchangé.
- Le mode RAW reste disponible via
PC15_PAYLOAD_FMT=RAW
(debug).
Retour
dict: {"bitstream": bytes, "bpp": float, "stats": dict, "tile_map": []} - stats["tiles_info"] trace (tid, choix, score, bits, D)
_grid_rects(H, W, tile, overlap)
¶
decode_y(bitstream, device='cpu')
¶
Décode un flux v15 et reconstruit une image Y non nulle (Step 4).
- Valide ANS0/RAW par record.
- Synthèse CPU-only par tuile (motif stripes basé sur la seed).
- Assemblage via fenêtre Hann (
tiling.blend
).
NB : on ignore encore le contenu symbolique pour la synthèse (les offsets choisis à l’encodage ne sont pas reconsommés ici — ce sera l’objet d’un step ultérieur quand le rendu “réel” sera branché).
__all__ = ['read_bitstream', 'write_bitstream', 'pack_v15', 'unpack_v15', 'TileRec', 'pack_records_v15', 'unpack_records_v15', 'write_stream_v15', 'read_stream_v15']
module-attribute
¶
TileRec
dataclass
¶
Enregistrement de tuile (Step 1, version simple). Note: pas encore d'encodage rANS ici (payload=b"" possible).
tile_id
instance-attribute
¶
gen_id
instance-attribute
¶
qv_id
instance-attribute
¶
seed
instance-attribute
¶
rec_flags = 0
class-attribute
instance-attribute
¶
payload_fmt = 0
class-attribute
instance-attribute
¶
payload = field(default_factory=bytes)
class-attribute
instance-attribute
¶
to_dict()
¶
from_dict(d)
staticmethod
¶
read_bitstream(path)
¶
Read a bitstream from disk (raw bytes).
write_bitstream(payload, path)
¶
Atomic write to target path. # [STORE:OVERWRITE]
pack_v15(h)
¶
Pack header dict into bytes with MAGIC|VER|LEN|JSON|CRC. Returns bytes suitable for writing to disk. # [STORE:OVERWRITE]
unpack_v15(b)
¶
pack_records_v15(recs)
¶
Packe une liste de TileRec → bytes (v15).
unpack_records_v15(b)
¶
Parse bytes → liste de TileRec (v15) avec vérif CRC par record.
write_stream_v15(header_dict, records)
¶
Concatène header v15 (pack_v15) + bloc records v15 (pack_records_v15).
read_stream_v15(buf)
¶
Sépare et décode header v15 + bloc records v15 depuis un flux binaire unique.
TileGridCfg
dataclass
¶
TileBatchSpec
dataclass
¶
_start_indices(L, size, overlap)
¶
Positions de départ couvrant [0, L) avec overlap. Stride = size - overlap. Ne dépasse jamais L-size. Toujours trié croissant.
tile_image(y, grid)
¶
Prépare la grille de tuiles pour une image Y [1,1,H,W].
_hann_1d(n, overlap, device, dtype)
¶
_tukey_1d(n, alpha, device, dtype)
¶
Fenêtre de Tukey (alpha in [0,1]) : plateau central + cos aux bords.
_kaiser_1d(n, beta, device, dtype)
¶
Fenêtre de Kaiser. Beta ~ 6–8 donne des bords propres.
_window_2d(size, overlap, device, dtype, kind='hann', params=None)
¶
Construit une fenêtre 2D séparée (wy ⊗ wx).
seam_penalty_mask(size, overlap, power=1.0, device=None, dtype=None)
¶
Masque [size,size] proche de 1 aux bords, 0 au centre. À utiliser comme poids additionnel dans le score RD pour pénaliser les coutures.
power>1 accentue la pénalité aux bords. Si overlap=0 → zeros.
blend(tiles, spec, H, W, window='hann', window_params=None, eps=1e-08)
¶
Assemble des tuiles [N,1,size,size] en une image [1,1,H,W] avec blend normalisé.
- window: 'hann' (defaut) | 'tukey' | 'kaiser'
- window_params:
- 'tukey': {'alpha': float in [0,1]} par défaut alpha=2*overlap/size clampé
- 'kaiser': {'beta': float} par défaut 6.5
SearchCfg
dataclass
¶
Configuration de scoring RD.
- lambda_rd : poids du terme "bits" (R) dans RD = D + lambda_rd * R
- metric : "ssim" (par défaut), "mse", ou "mixed" (pondère SSIM/MSE via alpha)
- alpha : poids de SSIM dans le mode "mixed" (D = alpha(1-ssim) + (1-alpha)MSE)
- beam_k : réservé pour beam-search (non utilisé ici)
- early_exit_tau : seuil d'early exit (non utilisé ici)
ScoreOut
dataclass
¶
make_border_mask(h, w, width=8, device=None, dtype=None)
¶
Crée un masque binaire (1 sur les bords, 0 ailleurs), shape (1,1,H,W). width=0 → masque nul (aucun bord).
score_batch(y_tile, synth, cfg, seam_weight=0.0, border_mask=None)
¶
Calcule D, R, RD pour un batch de synthèses 'synth' (B,1,H,W) vs la tuile 'y_tile' (1,1,H,W).
- D:
- "ssim" → 1 - SSIM(y, ŷ)
- "mse" → mean((y - ŷ)^2)
- "mixed" → alpha(1-SSIM) + (1-alpha)MSE (alpha dans cfg)
- Pénalité couture: si seam_weight>0, ajoute seam_weight * MSE sur la zone de bord (border_mask). Si border_mask=None, il est généré automatiquement (width=8).
- R: proxy bits (placeholder = 1.0 pour S1, donc constante)
- RD: D + lambda_rd * R
score_batch_bits(y_tile, synth, cfg, *, bits_est=None, bits=None, seam_weight=0.0, border_mask=None)
¶
Variante où le coût "bits" (R) est fourni par l'appelant, shape (B,).
Compat :
- bits_est=
(ancien nom utilisé par certains tests)
- bits=
(nom recommandé)
- D: même calcul que score_batch (SSIM/MSE/mixed + couture optionnelle)
- R: = bits fournis
- RD: D + lambda_rd * R
grid_linspace(bounds, steps, device=None, dtype=None)
¶
Crée une grille régulière D-dimensionnelle. bounds: [(min_d, max_d)] pour d=0..D-1 steps: [S_d] nombre d'échantillons par dimension return: (N, D) avec N = prod(S_d)
local_refine(center, deltas, steps)
¶
Grille locale autour d'un centre (D,) avec amplitude 'deltas' (D,). Pour chaque dim d: linspace(center[d]-deltas[d], center[d]+deltas[d], steps[d]). return: (N,D)
select_best_param_from_scores(params, scores)
¶
params: (N,D) paramètres candidats scores: (N,) coût (plus petit = meilleur) return: (param_best(D,), index)
clamp_params(params, bounds)
¶
Coupe chaque dimension de params (N,D) dans les bornes fournies.
topk_indices(scores, k)
¶
Indices des k meilleurs scores (croissants).
score_rd_numpy(y, recon, *, lam=None, lambda_rd=0.02, alpha=0.7, bits_est=None, bits=None, metric='ssim')
¶
Version NumPy, sans torch. Objectif: simple et déterministe pour tests rapides.
Compat (legacy):
- lam
: alias de lambda_rd
- bits_est
: alias de bits
Retourne un scalaire RD = D + lambda_rd * bits.
Notes: - Pour metric="ssim", on utilise ici un proxy basé sur la MSE (c'est suffisant pour les tests qui ne vérifient que l'ordre: "bon" < "mauvais" et la finitude).
DEFAULT_TABLE_ID = 'v15_default'
module-attribute
¶
__all__ = ['load_table_by_id', 'DEFAULT_TABLE_ID', 'available_tables']
module-attribute
¶
load_table_by_id(table_id, paths=None)
¶
Charge une table rANS gelée par son identifiant et la convertit vers le format canonique attendu par rans_impl.
Ordre de résolution (du plus prioritaire au moins prioritaire) :
0) ENV PC15_RANS_TABLES
→ pc15codec/data/rans/<table_id>.json
Caching : - Résultat mis en cache mémoire selon la clé (env_root, models_root, table_id) pour éviter des I/O répétées (après coercition). - Changer d’ENV ou de models dir invalide implicitement la clé.
Exceptions
FileNotFoundError si aucune source ne fournit table_id
.
ValueError si le contenu JSON est invalide ou non convertible.
available_tables(paths=None)
¶
Énumère les tables disponibles en agrégeant les trois sources :
- ENV PC15_RANS_TABLES
(si défini) — priorité 0
- pc15codec.data.rans
— priorité 2
L’ordre de la liste retournée est alphabétique et dédupliqué.
Retour
list[str] Liste d’identifiants (stems) disponibles, ex. ["v15_default", "custom_A", ...].
DEFAULT_TABLE_ID = 'v15_default'
module-attribute
¶
__all__ = ['ANS0_FMT', 'RAW_FMT', 'encode_tile_payload', 'decode_tile_payload', 'encode_tile_payload_raw', 'decode_tile_payload_raw']
module-attribute
¶
ANS0_FMT = 0
module-attribute
¶
RAW_FMT = 1
module-attribute
¶
pack_symbols(gen_id, qv_id, seed, flags, offsets)
¶
unpack_symbols(syms)
¶
rans_encode(symbols, tables_or_id, precision=None)
¶
Encode une liste de symboles 0..255 avec rANS.
- Si
tables_or_id
eststr
(table_id) : écrit l'entête ANS0 (MAGIC + u8 L + table_id ASCII) puis le flux core (u32 nsym | u32 state | chunks), en chargeant les tables viapc15codec.rans.load_table_by_id(table_id)
. - Si
tables_or_id
est un dict de tables : retourne uniquement le flux core (sans entête ANS0).
rans_decode(payload, tables_loader=None)
¶
Décode un payload ANS0.
- Lit MAGIC
, L
, table_id
.
- Charge les tables via tables_loader(table_id)
(par défaut pc15codec.rans.load_table_by_id
).
- Décode le flux core et retourne la liste des symboles.
NB: Les payloads sans entête ANS0 ne sont pas supportés ici.
encode_tile_payload(gen_id, qv_id, seed, flags, offsets, table_id=DEFAULT_TABLE_ID)
¶
Encode les symboles de tuile en payload ANS0 (rANS).
Paramètres
gen_id : int
Identifiant du générateur procédural sélectionné pour la tuile.
qv_id : int
Identifiant de la quantification vectorielle (codebook/entrée).
seed : int
Graine (seed) déterministe pour la synthèse de la tuile.
flags : int
Bits d’options/état pour la tuile.
offsets : List[int]
Offsets fins et/ou paramètres additionnels (liste bornée par pack_symbols
).
table_id : str, par défaut DEFAULT_TABLE_ID
Identifiant de tables rANS gelées à utiliser (ex: "v15_default").
Retour
(fmt, payload) : (int, bytes)
- fmt == ANS0_FMT
(0)
- payload
commence par b"ANS0"
puis contient table_id
et le flux rANS.
Détails
- Les champs
(gen_id, qv_id, seed, flags, offsets)
sont packés en une suite de symboles 0..255 viapack_symbols(...)
. - La liste de symboles est compressée via rANS avec les tables référencées
par
table_id
. L’en-tête ANS0 est automatiquement préfixé parrans_encode
.
Exceptions
TypeError / ValueError si les types/tailles sortent des bornes définies par
pack_symbols
ou si table_id
est invalide.
decode_tile_payload(payload)
¶
Décode un payload ANS0 (rANS) vers les symboles de tuile.
Paramètres
payload : bytes
Flux produit par encode_tile_payload(...)
(entête b"ANS0" attendu).
Retour
(gen_id, qv_id, seed, flags, offsets) : Tuple[int, int, int, int, List[int]]
Détails
rans_decode
vérifie l’entêteANS0
, littable_id
, charge les tables, puis reconstruit la liste de symboles 0..255.unpack_symbols
reconstitue la 5-uplet(gen_id, qv_id, seed, flags, offsets)
.
Exceptions
ValueError si l’entête est invalide ou si le stream est corrompu.
encode_tile_payload_raw(data)
¶
Encode RAW → (fmt, payload)
pour debug/compatibilité.
Paramètres
data : bytes Octets à passer tels quels.
Retour
(fmt, payload) : (int, bytes)
- fmt == RAW_FMT
(1)
- payload == data
(copie immuable)
Remarque
Ce mode bypass l’entropie et ne doit pas être utilisé en production.
decode_tile_payload_raw(fmt, payload)
¶
Décode (fmt, payload)
lorsque fmt == RAW_FMT
.
Paramètres
fmt : int
Doit valoir RAW_FMT
(1).
payload : bytes
Octets encodés précédemment en mode RAW.
Retour
bytes Les octets d’origine.
Exceptions
ValueError si fmt != RAW_FMT
.
TypeError si payload
n’est pas un buffer d’octets.
__all__ = ['train_qv_numpy', 'quantize_params', 'dequantize_params', 'serialize_codebook', 'deserialize_codebook']
module-attribute
¶
_kmeans_pp_init(X, k, rng)
¶
Initialisation kmeans++ déterministe (seed du rng fourni).
train_qv_numpy(data, k, seed=1234, iters=50, tol=1e-06)
¶
Entraîne un codebook QV (k x d) via kmeans (Lloyd) simple. - data: (N, d) float32/float64 - k: nombre de vecteurs de code - seed: déterminisme complet
quantize_params(vec, codebook, scales=1.0)
¶
Choisit l’entrée de codebook la plus proche (L2) et code les offsets signés
en entiers bornés [-128,127] avec un pas scales
(par dimension).
offsets = clip(round((vec - code) / scales), -128..127)
dequantize_params(idx, offsets, codebook, scales=1.0)
¶
Reconstitue une approx: codebook[idx] + offsets * scales (avec broadcast).
serialize_codebook(codebook)
¶
Sérialisation simple binaire: u32 k, u32 d, puis k*d float32 row-major.
deserialize_codebook(data)
¶
Inverse de serialize_codebook.