Projet C - Encodeur JPEG

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

Cette page tente de rassembler les questions les plus fréquentes pour le sujet « Encodeur 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 de départ

L'archive de départ du projet se trouve dans les documents Chamilo du cours 3MMPLC : jpeg2018.tar.gz

Mises à jour

Vous trouverez ici une version à jour des modules et exécutables prof, avec un court changelog expliquant ce qui a été corrigé/ajouté.

La dernière version des modules profs (v5, 29/05/18) est disponible dans l'archive jpeg-bin-v5.tar.gz.

La dernière version du sujet PDF (v2, 17/05/18) est disponible ici: sujet_jpeg_v2.pdf

v5, 29/05/18

  • ppm2blabla

Correction d'un bug sur le remplissage à droite et en bas des MCUs dans le cas d'une image dont les dimensions ne sont pas multiples de 8.

v4, 22/05/18

  • ppm2blabla

Correction d'un bug d'arrondi dans le calcul des échantillons Y, Cb, Cr.

v3, 17/05/18

  • jpeg_writer.h

Suppression des fonctions jpeg_desc_set/get_dct(), hors sujet!

  • ppm2blabla

Génération de traces pour la partie encodage AC/DC

v2, 17/05/18

  • jpeg_writer_prof.o

Modification du comportement de jpeg_desc_destroy() : cette fonction ne libère plus la mémoire associée aux tables de Huffman. C'est à l'utilisateur de libérer lui-même les tables qu'il a allouées avec huffman_table_build().

  • ppm2blabla

Amélioration de l'affichage des valeurs "niveaux de gris" dans le fichier .bla généré lorsqu'on traite une image PGM.

  • tous modules

Ajout d'un tag de version des modules profs utilisés, affiché lorsque vous lancez ppm2jpeg :

**** [v2] REF Module: jpeg_writer ****

De la même façon, la version en cours d'utilisation est ajoutée à la trace générée par ppm2blabla.

Amphi de présentation

Les slides de l'amphi de présentation sont ici : amphi_jpeg.pdf

FAQ

Je ne trouve pas exactement les mêmes valeurs que l'exemple en annexe A du sujet

C'est normal! Il peut y avoir de légères différences dans les valeurs obtenues aux différentes étapes (DCT, sous échantillonnage, ...) dues aux arrondis (quelle méthode d'arrondi, quelle implémentation de la fonction d'arrondi, combien de chiffres significatifs, ...). Vous pouvez demander à votre prof d'archi préféré qu'il vous explique pourquoi.

Ne perdez donc pas votre temps à essayer d'obtenir exactement les mêmes valeurs que dans le sujet. Par contre, si la différence devient grande, c'est que vous calculez faux quelque part.

Argh! Je dois calculer faux parce que le sujet indique 0000 et moi j'obtiens ffff

Peut-être pas? ffff en entier signé 16 bits, ça fait -1, c'est pas si loin que ça de 0, pas vrai?

Ca fait 10 jours que je suis sur la DCT, et les valeurs que je calcule sont toutes super loin de celles du sujet

Avez-vous la dernière version du sujet? Il y avait une coquille dans la formule de DCT donnée dans la version initiale du sujet PDF. La bonne formule est : Dct.png

Elle est disponible à partir de la version v2 du sujet PDF (voir au-dessus).

Pfff super! Tout ça parce que le sujet était faux!

Oui, c'est pas de bol. Mais quand c'est le cas, on corrige le tir à la vitesse de l'éclair, on passe dans les salles pour dire aux étudiants présents qu'il faut récupérer une nouvelle version du sujet/des .o prof ET on envoie un mail.

Si vous avez fait le choix de travailler à distance et de ne pas ouvrir vos mails, c'est dommage!

ppm2blabla affiche des valeurs sur 3 octets pour les échantillons de l'image source PGM

Vrai, ppm2blabla affichait trois octets (RGB) même quand on traite une image en niveaux de gris. On se retrouvait du coup avec des choses du genre 0000ff au lieu de ff dans l'encart "Valeurs RGB initiales". L'affichage a été corrigé dans la v2 (voir ci-dessus), pour représenter les échantillons PGM sur un octet, tels qu'ils figurent dans l'image source.

Le sujet dit qu'il n'existe pas de fonction set/get pour les tables de quantification (section C.2) alors que jpeg_writer.h dit que si, qui a raison?

En fait si, et c'est à vous d'appeler jpeg_desc_set_quantization_table() avant d'appeler jpeg_write_header(), de la même manière que pour les tables de Huffman (corrigé à partir de la v2 du sujet PDF).

Quand j'appelle jpeg_write_header() et que je regarde le fichier généré, je ne trouve pas l'entête jpeg

Il y a de fortes chances que vous utilisiez mal le bitstream associé. jpeg_write_header() créé lui-même le bitstream dans lequel il écrit l'entête jpeg (p55 du sujet). Si vous créez un autre bitstream et que vous écrivez dedans, vous réinitialisez le fichier de sortie à zéro, et l'entête écrite par jpeg_write_header() disparait. Appelez jpeg_desc_get_bitstream() pour récupérer le bitstream créé par jpeg_write_header().

Quand je regarde le contenu d'un fichier avec hexdump, les octets ne sont pas dans le bon ordre!

Attention à l'endianness! Utilisez l'option -C pour lire votre fichier octet par octet.

On doit bien écrire End of Block à la fin de chaque bloc, pas vrai?

Non, EOB correspond à un code RLE qui indique que le bloc en cours d'encodage ne contient plus que des coefficients à 0.

Et le byte stuffing, c'est à nous de le gérer?

Le byte stuffing est géré par le module bitstream. L'activation du byte stuffing se fait à l'aide du dernier paramètre de la fonction bitstream_write_nbits().

Le point sur les tailles de MCU dans le cas gris

Lorsqu'on traite des images à une seule composante de couleur (noir et blanc), l'ordonnancement des blocs au sein d'une MCU est différent du cas général (3 composantes de couleur, Y, Cb et Cr). Cette partie est détaillée en section 2.7.2 du sujet. Dans le cas gris, les blocs de l'image sont écrits comme si on travaillait sur des MCUs de taille 1x1, et ce quelle que soit la taille de MCU spécifiée. Dans la pratique, beaucoup d'encodeurs jpeg simplifient le problème (dont ppm2blabla) en n'autorisant que des MCUs de taille 1x1 pour traiter les images noir et blanc, puisque travailler sur des tailles de MCU différentes de 1x1 dans le cas gris n'apporte rien dans le cas que nous traitons (JPEG baseline séquentiel DCT huffman).

jpeg2blabla: rien compris

jpeg2blabla blablate. En particulier, il raconte comment il décode les coefficients AC/DC. Exemple:

*** 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)