# B3 — Le musée des octets

## Avant de commencer

Ce carnet facultatif reprend les octets et les motifs binaires étudiés en AP3. Il ne constitue pas un devoir supplémentaire. Si je le retiens comme bonus pour un cycle, je préciserai en cours les exercices attendus, le dossier de dépôt et l’échéance. Les anciennes dates de remise ne s’appliquent plus.

## Le sujet

Nous allons fabriquer un petit format d'image plutôt que dépendre d'un format existant. Une image du musée commence par `"MUSE"`, puis sa largeur et sa hauteur sur 16 bits non signés, big-endian, puis un octet de gris par pixel, ligne par ligne.

Écrivez `Museum.encode(width, height, pixels)` et `Museum.decode(binary)`. Le décodeur renvoie `{:ok, %{width: w, height: h, pixels: pixels}}` ou `{:error, :invalid}`. Une dimension nulle, un pixel manquant ou un octet en trop rend le fichier invalide. L'encodeur refuse les dimensions hors de `1..65535`, les valeurs hors de `0..255` et les listes de mauvaise longueur avec `ArgumentError`.

Gardez le calcul des tailles explicite : le nombre de pixels vaut largeur × hauteur. Pouvez-vous repérer une corruption qui conserve cette taille ? Expliquez pourquoi ce format ne la détecte pas.

## À vous

```elixir
defmodule Museum do
  def encode(width, height, pixels), do: nil
  def decode(binary), do: nil
end
```

## Vérifications

```elixir
expected = %{width: 2, height: 2, pixels: [0, 80, 160, 255]}
encoded = Museum.encode(2, 2, expected.pixels)
true = encoded == <<"MUSE", 2::16, 2::16, 0, 80, 160, 255>>
{:ok, ^expected} = Museum.decode(encoded)
for invalid <- [<<>>, <<"MUSE", 0::16, 1::16>>, binary_part(encoded, 0, byte_size(encoded) - 1), encoded <> <<0>>] do
  {:error, :invalid} = Museum.decode(invalid)
end
for {w, h, pixels} <- [{0, 1, []}, {65536, 1, []}, {1, 1, [256]}, {2, 1, [0]}] do
  rejected = try do
    Museum.encode(w, h, pixels)
    false
  rescue
    ArgumentError -> true
  end
  true = rejected
end
IO.puts("Format vérifié")
```

## Votre explication

Ajoutez une cellule Markdown pour expliquer votre démarche, les cas limites vérifiés et ce que vous avez observé. Pour toute question : aurelien.noce@minesparis.psl.eu, avec aurelien.noce@imagine-app.fr en copie.
