Opérations bit à bit

✎ Travail n° 1 Opérateurs de base

Réaliser les opérations suivantes :

  • 0x4C & 0xC6

  • 0xA5 | 0x22

  • ~ 0x0F

  • 0xC3 ^ 0x66

  • 0x96 << 2

Solution
  • 0x4C & 0xC6

      0100 1100
    & 1100 0110
    -----------
      0100 0100

    Résultat : 0100 0100|2 ⇒ 0x44

  • 0xA5 | 0x22

      1010 0101
    | 0010 0010
    -----------
      1010 0111

    Résultat : 1010 0111|2 ⇒ 0xA7

  • ~ 0x0F

    ~ 0000 1111
          ⇓
      1111 0000

    Résultat : 1111 0000|2 ⇒ 0xF0

  • 0xC3 ^ 0x66

      1100 0011
    | 0110 0110
    -----------
      1010 0101

    Résultat : 1010 0101|2 ⇒ 0xA5

  • 0x96 << 2

        [1001 0110]
             ⇓
    1 ⤺ [0010 1100] ⤺ 0
             ⇓
    0 ⤺ [0101 1000] ⤺ 0

    Résultat : 0101 1000|2 ⇒ 0x58

✎ Travail n° 2 Opérations combinées

  1. Calculer 0x0F | (1 << 2) puis 0xF0 | (1 << 2)

    Solution :
    * (1 << 2) :              ⤺          ⤺
           0000 0001 → 0000 0010 → 0000 0100
    
    * 0x0F | (1 << 2) :
           0000 1111
         | 0000 0100
         -----------
           0000 1111 ⇒ 0x0F
    
    * 0xF0 | (1 << 2) :
           1111 0000
         | 0000 0100
         -----------
           1111 0100 ⇒ 0xF4
  2. Que peut-on en conclure sur l’expression générale :

    valeur-entière | (1 << rang-bit)
    Solution

    Cette expression permet de forcer à 1 le bit de rang rang-bit dans valeur-entière

  3. Calculer 0x96 & ~(1 << 2) puis 0x69 & ~(1 << 2)

    Solution :
    * (1 << 2) :              ⤺          ⤺
           0000 0001 → 0000 0010 → 0000 0100
    
    * ~(1 << 2) :
           0000 0100 → 1111 1011
    
    * 0x96 & ~(1 << 2) :
           1001 0110
         & 1111 1011
         -----------
           1001 0010 ⇒ 0x92
    
    * 0x69 & ~(1 << 2) :
           0110 1001
         & 1111 1011
         -----------
           0110 1001 ⇒ 0x69
  4. Que peut-on en conclure sur l’expression générale :

    valeur-entière & ~(1 << rang-bit)
    Solution

    Cette expression permet de forcer à 0 le bit de rang rang-bit dans valeur-entière.

  5. Calculer 0xC3 ^ (1 << 2) puis 0x3C ^ (1 << 2)

    Solution :
    * (1 << 2) :              ⤺          ⤺
           0000 0001 → 0000 0010 → 0000 0100
    
    * 0xC3 ^ (1 << 2) :
           1100 0011
         & 0000 0100
         -----------
           1100 0111 ⇒ 0xC7
    
    * 0x3C ^ (1 << 2) :
           0011 1100
         & 0000 0100
         -----------
           0011 1000 ⇒ 0x38
  6. Que peut-on en conclure sur l’expression générale :

    valeur-entière ^ (1 << rang-bit)
    Solution

    Cette expression permet d'inverser le bit de rang rang-bit dans valeur-entière.

💻 Travail n° 3 Analyse données EXIF

🕮 Apport de connaissances :

Les images prises à partir d’un appareil photo contiennent en général un ensemble d’informations sur la prise de vue sous la forme de métadonnées qui répondent au format EXIF.

On vous demande de compléter un script Python pour afficher les informations de prise de vue concernant l’utilisation du flash.

Ces informations sont codées dans plusieurs champs au sein d’un seul octet :

  • bit 0 : déclenchement du flash

    • 0 → pas déclenché

    • 1 → déclenché

  • bits 1-2 : retour du flash

    • 00 → fonction absente

    • 01 → réservé

    • 10 → non détecté

    • 11 → détecté

  • bits 3-4 : mode d’utilisation du flash

    • 00 → inconnu

    • 01 → forcé

    • 10 → désactivé

    • 11 → auto

  • bit 5 : présence d’une fonction flash

    • 0 → oui

    • 1 → non

  • bit 6 : fonction de reduction d’yeux rouges

    • 0 → non

    • 1 → oui

On vous fournit le code partiel d’un script Python :

Code partiel
from PIL import Image

def getExifFlashInfo(filePath) :
    '''
    Retourne les informations du flash présentes dans les données EXIF d'une photo
    '''
    # Lecture de l'image
    image = Image.open(filePath)

    # Extraction des métadonnées
    exifdata = image.getexif()

    # Extraction des données EXIF depuis les métadonnées
    exifIfd = exifdata.get_ifd(0x8769)

    # Extraction de la donnée EXIF concernant l'utilisation du flash
    flashInfo = exifIfd.get(0x9209)

    return flashInfo

# Extraction des informations du flash d'une photo
# (plusieurs champs de longueur variable codés dans un octet)
flash = getExifFlashInfo("redeyes.jpg")

# Affichage de l'octet "brut"
print("Informations du flash :")
print(f"{'. Valeur':32} : {flash} ({flash:08b})") # <libellé sur 32 caractères> : <valeur décimale> (<valeur binaire sur 8 bits>)

# Analyse du bit 0 (flash déclenché ou non)
if( flash & 0b00000001 != 0 ) :
    isFlashOn = "oui"
else :
    isFlashOn = "non"
print(f"{'. Déclenchement du flash':32} : {isFlashOn}")

# Analyse des bits 1 et 2 (état du retour flash)
match( (flash >> 1) & 0b00000011 ) :
    case 0b00 :
        retourFlash = "fonction absente"
    case 0b01 :
        retourFlash = "réservé"
    case 0b10 :
        retourFlash = "non détecté"
    case 0b11 :
        retourFlash = "détecté"
print(f"{'. Retour flash':32} : {retourFlash}")

# Analyse des bits 3 et 4 (mode flash)
# <A COMPLETER>

# Analyse du bit 5 (présence d'une fonction flash)
# #<A COMPLETER>

# Analyse du bit 6 (fonction réduction yeux rouges activée ou non)
# #<A COMPLETER>

Ce code définit une fonction getExifFlashInfo(filePath) qui extrait l’octet contenant les informations d’utilisation du flash pour la photo dont le chemin est fourni en argument.

Le script appelle cette fonction pour extraire l’octet d’utilisation du flash depuis l’image redeyes.jpg puis affiche :

  • la valeur de l’octet en décimal et binaire

  • le résultat de l’analyse du bit 0 de cet octet (→ flash déclenché ou non)

  • le résultat de l’analyse des bits 1 et 2 (→ état du retour de flash)

🎯 Travail à faire :

  1. [A faire uniquement par ceux qui utilise le Python installé localement sur leur machine]
    Installer le module Python de traitement d’image nommé pillow. Pour cela :

    • lancer une console Python (→ taper “Anaconda prompt (miniconda3)” dans le menu “Démarrer” de Windows)

    • se déplacer dans l’environnement “co-math” avec :

      (base) C:\Users\claud>conda activate co-math (1)
      1 commande qui permet de basculer dans l’environnement “co-math”
    • installer le module pillow

      conda install -c anaconda pillow
  2. Copier le code Python fourni plus haut dans l’éditeur Python (→ VSCode ou Basthon) et le sauver dans votre répertoire de travail.

  3. Télécharger localement dans votre répertoire de travail cet exemple de photo img

    Pour ceux qui utilisent Basthon, uploader ce fichier sur la plateforme en sélectionnant l’icône upload basthon

  4. Exécuter le script partiel pour vérifier que tout fonctionne. Le script doit provoquer l’affichage suivant :

    Informations du flash :
    . Valeur                         : 29 (00011101)
    . Déclenchement du flash         : oui
    . Retour flash                   : non détecté
  5. Analyser le code fourni et le compléter pour afficher le résultat de l’analyse de tous les bits présents dans l’octet d’information sur l’utilisation du flash

    Résultat attendu pour la photo redeyes.jpg :
    Informations du flash :
    . Valeur                         : 29 (00011101)
    . Déclenchement du flash         : oui
    . Retour flash                   : non détecté
    . Mode flash                     : auto
    . Fonction flash                 : non
    . Fonction réduction yeux rouges : non
  6. Tester le code avec d’autres photos provenant de votre téléphone portable ou d’internet

🞄  🞄  🞄