Projet C - Décodeur JPEG

De Ensiwiki
Aller à : navigation, rechercher
Char-shaun.png

Cette page tente de rassembler les questions les plus fréquentes pour le sujet « Décodeur JPEG ». Vous pouvez ajouter vos questions en bas de la page, et éventuellement répondre aux questions de vos collègues, tant que vous le faites en respectant les règles du jeu : ne donnez pas de solutions explicites au sujet, n'échangez pas de code, et en cas de doutes, demandez à vos enseignants !

Retour à la page d'accueil principale du Projet C.

Encadrants JPEG

Voici la liste des encadrants pour le sujet JPEG, auxquels vous pourrez poser vos questions pendant les séances encadrées (Bat E 1er étage, camp de base en E103) :

Ressources projet

Archive initiale

Commencez par télécharger l'archive suivante : squelette-jpeg.tar.gz

Cette archive contient tout ce qu'il faut pour démarrer, à savoir :

  • Le sujet, au format PDF (sujet_jpeg.pdf) qui doit être votre source principale d'information
  • Les fichiers d'entête huffman.h, bitstream.h et jpeg_reader.h
  • Les fichiers objet binaires huffman, bitstream et jpeg_reader huffman.o, bitstream.o et jpeg_reader.o
  • Un fichier Makefile de départ
  • Les images de test de difficulté progressive, comme présentées dans le sujet
  • La spec JPEG, si vous ressentez le besoin d'approfondir les notions abordées par le sujet (dans le répertoire docs)
Attentionle squelette a été généré pour l'architecture x86_64 des machines de l'école. Les objets distribués ne sont donc pas utilisables sur une machine perso configurée différemment (32 bits, MacOS, ...).

Dans ce cas, la (seule) solution est de travailler via la virtualisation, accessible via un navigateur.

La page de connexion est https://pcvirtuel.ensimag.fr, avec une doc explicative ici. En cas de problème lié à la virtualisation, merci de contacter le service informatique: support.info@ensimag.fr (ou même dans ce cas aller directement les voir, tout fond à droite du bâtiment E 2ème étage).


iDCT rapide

Article de référence sur l'algorithme de Loeffler: Loeffler.pdf

Il y a quelques typos dans le papier original (!) :

  • en figure 1: la rotation de l'étape 3 entre les coefficients 2 et 3 \sqrt{2} c_1 doit être remplacée par \sqrt{2} c_6
  • en figure 2, les sorties du butterfly et de la rotation sont bien sûr O_0 (1ère ligne) et O_1 (deuxième ligne), et pas deux fois O_0.

Les indices à droite du schéma de l'article ne sont valides que pour un étage de l'algorithme. Dans le sens DCT, on effectue donc les 3 premiers étages avec les indices normaux, puis on écrit le résultat du dernier étage aux indices réordonnés. Dans le sens IDCT, on lit les entrées du premier étage avec les indices réordonnés, mais les résultats de cet étage (et des suivants) s'écrivent avec les indices normaux (de 0 à 7 dans l'ordre).

De même, l'IDCT est une inversion de la DCT. La rotation ne s'effectue donc pas dans le même sens :

0_0 = I_0 . k . \cos\left(\frac{n\pi}{16}\right) - I_1 . k . \sin\left(\frac{n\pi}{16}\right)

0_1 = I_1 . k . \cos\left(\frac{n\pi}{16}\right) + I_0 . k . \sin\left(\frac{n\pi}{16}\right)

Questions diverses

Comment je fais pour générer des images JPEG avec des facteurs d'échantillonnage exotiques?

Vraiment, ce serait tordu de penser que vos profs sortiront des images comme ça pendant la soutenance... Mais pour répondre à la question, essayez ça dans un terminal :

/matieres/3MMPLC/JPEG/cjpeg --help

En pratique, on fait comme ça pour générer un jpeg 4:2:0 avec des MCUs de 2x2 blocs :

/matieres/3MMPLC/JPEG/cjpeg -sample 2x2,1x1,1x1 truc.ppm > truc.jpg

Précisions sujet / Errata

Quelques clarifications diverses et variées:

No comment

Le programme jpeg2blabla distribué ne gère actuellement pas les commentaires, et affiche un message (warning) disant que le token fe n'est pas supporté. C'est un bête oubli de notre part! C'est corrigé dans la nouvelle version.

Encore plus de blabla: coefficients AC/DC

Une nouvelle version de jpeg2blabla est proposée, qui rajoute une ligne sur les coefficients DC et AC d'un bloc. Example:

*** mcu 17
** component Y
* bloc 0
[ DC/AC] 02(3) / 02(2) 21(5) 11(3) 11(3) 12(5) 21(5) 51(7) 00(5) -- total 49 bits
[  bloc] fed0 2 0 0 ffff 0 ffff 0 ffff 0 fffe 0 0 ffff 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

Comme lire ceci?

  • la magnitude du coefficient DC est 0x02, elle a été lue en consommant 3 bits (== profondeur du symbole 0x02 dans l'arbre de Huffman)
  • le premier coefficient AC est 0x02 (2 bits lus), le second 0x21 (5 bits lus), etc.
  • Au total 49 bits ont été consommés dans le flux pour récupérer tous les coefficients du bloc (nb de bits lus dans les arbres + les magnitudes trouvées)

Lien: Squelette-jpeg_add-ons.tar.gz‎

Encore plus de blabla: arbres de Huffman

Vous pouvez désormais voir la structure d'un arbre de Huffman, i.e. les chemins menant aux différents symboles.

Il suffit d'utiliser l'option -v -h (ou -vh) de jpeg2blabla:

[DHT]	length 31 bytes
		Huffman table type DC
		Huffman table index 0
		total nb of Huffman codes 12
		path: 00 symbol: 0
		path: 010 symbol: 1
		path: 011 symbol: 2
		path: 100 symbol: 3
		path: 101 symbol: 4
		path: 110 symbol: 5
		path: 1110 symbol: 6
		path: 11110 symbol: 7
		path: 111110 symbol: 8
		path: 1111110 symbol: 9
		path: 11111110 symbol: a
		path: 111111110 symbol: b

La nouvelle version est disponible dans le lien de la section précédente.

Encore plus de blabla: détails sur les arbres de Huffman

Une fonction a été rajoutée dans le module huffman:

extern int8_t next_huffman_value_count(struct huff_table *table,
                                       struct bitstream *stream,
                                       uint8_t *nb_bits_read);

En sortie, le nombre de bits consommés pour retrouver le symbole de Huffman (donc sa profondeur) est stocké à l'adresse nb_bits_read.

Cette fonction est un peu moins efficace que la précédente, ne l'utilisez que si vous en avez besoin. Le moment venu, vous n'êtes pas obligé de l'écrire dans votre propre module (sauf si vous vous en servez bien sûr).

Le nouveau fichier objet est dans la même archive que les ajouts sur AC/DC: Squelette-jpeg_add-ons.tar.gz‎

Fréquences et coefficients ("389 c'est pas une fréquence")

La formulation n'est pas toujours claire dans le sujet: dans un bloc décodé du flux JPEG, on ne stocke évidemment pas les fréquences mais les coefficients du signal à ces fréquences (l'amplitude des raies spectrales, en fait). Les fréquences elles-même dépendent des indices considérés: le signal spatial étant supposé périodique sur des blocs 8x8, les fréquences dans chaque direction horizontale et verticale valent \lambda/8 et \mu/8. C'est le principe de la transformée de Fourier discrète, ou en cosinus dans notre cas particulier.

Albums et pas album

Les images vertical.jpg et horizontal.jpg proviennent de deux albums différents! (et le piège est sur l'horizontale)