lecture des n prochains bits du buffer...

lecture des n prochains bits du buffer... - C - Programmation

Marsh Posté le 13-03-2005 à 17:04:16    

Hello,
 
j'ai donc un buffer qui pointe sur des octets.
Mais en fait les données ne sont pas enregistrées sous forme d'octets mais  sur un nombre variable de bits compris entre 1 et 16.
 
je cherche donc à faire : (uint)val = get_valeur_des_bits(buffer,nombre_de_bits_a_lire);
cette fonction lirait les n bits et les transformerait en int.
 
ensuite il faudra que je déplace le pointeur du nombre de bits lus pour pouvoir acceder à la valeur suivante... ( mais comment déplacer le pointeur de moins d'un octet ?? )
 
je suis un peu perdu, et je ne connais pas l'assembleur.
merci de me sauver la vie. :ange:


Message édité par jobigoud le 13-03-2005 à 17:07:57
Reply

Marsh Posté le 13-03-2005 à 17:04:16   

Reply

Marsh Posté le 13-03-2005 à 17:05:36    

On peut pas.
 
Il va falloir jouer du & pour récupérer les blocs :o


---------------
JE JE SUIS LIBERTINEEEEEEEEEEE JE SUIS UNE CATINNNNNNNNN §§§§§§§§
Reply

Marsh Posté le 13-03-2005 à 17:26:07    

elianor a écrit :

On peut pas.
 
Il va falloir jouer du & pour récupérer les blocs :o


 
bon...
j'ai pas trouvé avec des &...
mais par contre peut-etre avec des << et des >> ?
 
par exemple je suis aligné sur un octet et j'ai besoin de l'equivalent de la valeur des 5 prochains bits. je récupère d'abord les 16 bits d'un coup, puis je fait un:  
val_octets >> 9
ça devrait marcher...
mais maintenant comment me déplacer de seulement 5 bits pour acceder à la suite...?
(je peux peut-etre conserver l'écart en bits à l'alignement mais c'est un peu tiré par les cheuveux...)
 
Que fait l'opérateur >> si je lui donne un pointeur ? il me déplacerait pas mon buffer par hasard ? ( allez siouplait...)
 

Reply

Marsh Posté le 13-03-2005 à 17:26:30    

peut être un bout de code serait le bienvenu histoire d'un peu mieux comprendre ce qu'il faut que tu aies.

Reply

Marsh Posté le 13-03-2005 à 17:27:55    

jobigoud a écrit :

bon...
j'ai pas trouvé avec des &...
mais par contre peut-etre avec des << et des >> ?


 
ouais, aussi, mais la réponse est une combinaison de décalages et de ou.
 
Tu écris un décoimpresseur LZW ?


---------------
JE JE SUIS LIBERTINEEEEEEEEEEE JE SUIS UNE CATINNNNNNNNN §§§§§§§§
Reply

Marsh Posté le 13-03-2005 à 17:30:23    

>> avec un pointeur, c'est pas cool du tout
Dans quel ordre veux-tu extraire les bits ? En partant de la fin ou du début ?
 
Pour prendre les n bits de poids le plus fort, du décales de (nombre de bits total - n) vers la droite
 
Pour prendre les n bits de poids le plus faible, du décales de (nombre de bits total - n) vers la gauche puis vers la droite, mais c'est plus simple avec un &


Message édité par leneuf22 le 13-03-2005 à 17:40:20
Reply

Marsh Posté le 13-03-2005 à 17:43:26    

elianor a écrit :


Tu écris un décoimpresseur LZW ?


j'ecris un decodeur Huffman. enfin j'essaie.
 

leneuf22 a écrit :

>> avec un pointeur, c'est pas cool du tout
Dans quel ordre veux-tu extraire les bits ? En partant de la fin ou du début ?
 
Pour prendre les n bits de poids le plus fort, du décales de (nombre de bits total - n) vers la droite
 
Pour prendre les n bits de poids le plus faible, du décales de (nombre de bits total - n) vers la gauche


 
>> avec un pointeur pourquoi c'est pas cool ? je vais essayer tiens pour voir ce que ça fait...
je prends les n premiers bits qui viennent, donc je décale vers la droite pour virer ceux qui m'interresse pas pour l'instant.
 
 
 

Reply

Marsh Posté le 13-03-2005 à 18:20:31    

Bon, le code pour lire la valeur des n bits suivants marche bien.
le vlà si ça vous interresse :

Code :
  1. unsigned short int __fastcall getbits(unsigned char *buf, int n){
  2.     //récupère la valeur décimale des n prochains bits.
  3.     unsigned short int word;
  4.     word = ((int)buf[0]<<8) + (int)buf[1];
  5.     return word >> (16 - n);
  6. }


mais ça ça marche que dans le cadre ou le pointeur est déjà bien placé. (  par ex. à la première lecture )
mais maintenant je fais comment pour me déplacer et lire les prochains ??
je suis obligé de passer par une boucle en assembleur pour pouvoir lire ?
  :cry:


Message édité par jobigoud le 13-03-2005 à 18:31:45
Reply

Marsh Posté le 13-03-2005 à 18:51:51    

ok, je crois que j'ai quelque chose, dites moi ce que vous en pensez...
 
à tout moment on aurait en stock les 16 prochains bits du buffer pour être prêts à les lire avec la technique du dessus.
 
Après une lecture de n bits, il faut trouver les nouveaux 16 prochains.
pour ça, on récupère les 4 prochains octets depuis le pointeur d'ensemble et on rempli le petit avec les bits n à n+16.
 
On décalerai le gros pointeur seulement par bloc de 8 bits ( évidement)  
 
il faudrait donc garder en mémoire le nombre de bits de décalage et chaque fois qu'on est modulo 8 on déplace le gros pointeur.  
ah oui mais en fait il va y avoir un reste, donc il faudra prendre 3 octets au cas où...
 
bon, en me relisant je vois que c'est pas clair ! :lol:  
je vais le coder et je repasse...
 :hello:


Message édité par jobigoud le 13-03-2005 à 18:54:18
Reply

Marsh Posté le 13-03-2005 à 18:58:19    

jobigoud a écrit :

Bon, le code pour lire la valeur des n bits suivants marche bien.
le vlà si ça vous interresse :

Code :
  1. unsigned short int __fastcall getbits(unsigned char *buf, int n){
  2.     //récupère la valeur décimale des n prochains bits.
  3.     unsigned short int word;
  4.     word = ((int)buf[0]<<8) + (int)buf[1];
  5.     return word >> (16 - n);
  6. }


mais ça ça marche que dans le cadre ou le pointeur est déjà bien placé. (  par ex. à la première lecture )
mais maintenant je fais comment pour me déplacer et lire les prochains ??
je suis obligé de passer par une boucle en assembleur pour pouvoir lire ?
  :cry:


 
Tu ne peux lire au minimum qu'un octet.
Donc voici une idée pour que ta fonction marche
1) tu lis un (ou deux octets) que tu stockes dans une variable statique "tab"
2) tu renvoies le nb de bits qui t'intéressent et tu stockes dans une seconde variable statique le nb de bits envoyés (ou alors le nb de bits restants, c'est comme tu veux)
3) lors de l'appel suivant, tes variables statiques ont gardé les valeurs de l'appel précédent. Donc tu peux calculer si tu as, dans "tab" assez de bits pour répondre à la demande. Si c'est pas le cas, tu récupères à nouveau un (ou deux octets) pour répondre à la demande

Reply

Marsh Posté le 13-03-2005 à 18:58:19   

Reply

Marsh Posté le 13-03-2005 à 19:28:26    

Pour un décodeur Huffman ? Alors je vois pas pourquoi tu fais tout ça... C'est pour quelle étape que tu dois faire ça ? Lecture de l'entête ? Lecture des données ?

Reply

Marsh Posté le 14-03-2005 à 11:57:58    

leneuf22 a écrit :

Pour un décodeur Huffman ? Alors je vois pas pourquoi tu fais tout ça... C'est pour quelle étape que tu dois faire ça ? Lecture de l'entête ? Lecture des données ?


 
Bon, en fait c'est pour décoder un buffer contenant les données d'une image jpg. les données sont encodées par blocs de 8x8. je cherche à reconstruire ce vecteur de 64 octets. à l'encodage, certaines valeurs ont été éclatées en - d'un coté la catégorie de Hufman de la valeur ( = nombre de bits mini pour encoder la valeur) - et de l'autre la valeur elle-même sur ce nombre de bits ( allant de 1 à 15)
Je ne suis pas super familier avec la methode de compression en elle-même mais je pense avoir saisi l'algo de décompression.
 
pour mon (premier) souci j'ai une solution qui fonctionne. même si elle est pas très belle...
voilà ce que je fait:
 
j'ai 2 varaibles globales qui me conservent le décalage en octets entiers depuis le début du buffer, et le décalage en bits depuis le départ du dernier octet entier.
 
lecture de n bits :
 
on récupère 4 octets du buffer (grace au décalage en octets entiers )
on lit les n bits allant de decal_bits à decal_bits + n.
( pour ça je fait successivement un décalage vers la gauche puis un autre vers la droite.)
 
update de la position ( déplacement de n bits)
 
on était déjà décalé de decal_bits par rapport au début du premier octet.
On fait: nouveau_decalage <- decal_bits + n
par exemple on était décalé de 3 bits, on vient d'en lire 9.
on est maintenant décalé de 12 bits.
 
(nouveau_decal / 8) ici égal à 1, donne le nombre d'octet entiers qu'on vient de dépasser, on update le décalage en octets depuis le début du buffer avec.
(nouveau_decal mod 8) ici égal à 4, donne le nombre de bits restants, c'est le nouveau décal_bits de base.
 
ualà. j'espère que c'était clair...


Message édité par jobigoud le 14-03-2005 à 11:59:20
Reply

Marsh Posté le 14-03-2005 à 14:30:12    

jobigoud a écrit :

pour mon (premier) souci j'ai une solution qui fonctionne. même si elle est pas très belle...
voilà ce que je fait:
 
j'ai 2 varaibles globales qui me conservent le décalage en octets entiers depuis le début du buffer, et le décalage en bits depuis le départ du dernier octet entier.


T'as pas besoin de variables en global pour ça. Tu les mets en static dans ta fonction. Elles conserveront leur valeur même quand tu quittes la fonction et que tu y reviens plus tard.
Il faut absolument essayer d'éviter de mettre des globales autant que possible car xe n'est jamais "sain".
 

jobigoud a écrit :

(nouveau_decal / 8) ici égal à 1, donne le nombre d'octet entiers qu'on vient de dépasser, on update le décalage en octets depuis le début du buffer avec.


Là, soit tu t'es mal exprimé soit tu as fait une erreur de calcul.
Tu dis "n / 8" = nb d'octets entiers qu'on vient de dépasser. Donc, pour "n" variant de "1" à "8", tu dois avoir "nb dépassés = 0" puisque tu es tjrs sur le premier octet.
Or, si "n = 8", ta formule donne "nb dépassés = 1".
Donc, soit ton "n" varie de "0" à "7" et ta formule est correcte, soit il faut que tu fasses "(n - 1) / 8"
 

jobigoud a écrit :

(nouveau_decal mod 8) ici égal à 4, donne le nombre de bits restants, c'est le nouveau décal_bits de base.


si "nouveau décal" est à "9", le nb de bits restants est "7". Or ta formule donne "1". Elle te donne en fait la fraction d'octet que tu as pris au lieu de te donner les bits restants !!!
C'est "8 - (nouveau_decal mod 8)" qu'il te faut
 

jobigoud a écrit :

ualà. j'espère que c'était clair...


Tout à fait...

Reply

Marsh Posté le 14-03-2005 à 14:53:17    

Sve@r a écrit :

T'as pas besoin de variables en global pour ça. Tu les mets en static dans ta fonction.


C'est à peine mieux. Ok, ça réduit les accès sauvages, mais ça ne regle pas le problème de la non-réentrance et de l'instanciation multiple...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 14-03-2005 à 18:49:55    

Emmanuel Delahaye a écrit :

C'est à peine mieux. Ok, ça réduit les accès sauvages, mais ça ne regle pas le problème de la non-réentrance et de l'instanciation multiple...


 
uhahu ????  :??:

Reply

Marsh Posté le 15-03-2005 à 12:34:33    

Sve@r a écrit :

Là, soit tu t'es mal exprimé soit tu as fait une erreur de calcul.
Tu dis "n / 8" = nb d'octets entiers qu'on vient de dépasser. Donc, pour "n" variant de "1" à "8", tu dois avoir "nb dépassés = 0" puisque tu es tjrs sur le premier octet.
Or, si "n = 8", ta formule donne "nb dépassés = 1".
Donc, soit ton "n" varie de "0" à "7" et ta formule est correcte, soit il faut que tu fasses "(n - 1) / 8"


 
effectivement je me suis pas très bien exprimé...
 
n varie en fait de 0 à 15. et quand je dis dépassé, c'est pour signifier que la prochaine lecture ne devra plus se faire dans le même octet, donc je devrais plutôt dire completé...
 
si en entrée n = 8, et qu'on était en début d'octet, on lit les 8, le décalage en octet prend +1 (n/8) et le décalage en bits devient 0 ( n mod 8 ), la prochaine lecture se fera donc bien au bit zero de l'octet suivant comme convenu.
 
 

Sve@r a écrit :


si "nouveau décal" est à "9", le nb de bits restants est "7". Or ta formule donne "1". Elle te donne en fait la fraction d'octet que tu as pris au lieu de te donner les bits restants !!!


 
Ah, c'est parceque je n'ai pas pris le problème dans le même sens que ce que tu suggerais quelques messages plus haut...
la fraction d'octet que j'ai pris, c'est exactement ce que je veux. Ensuite je fais demarrer la lecture à l'octet courant + cette fraction.
 
Bon maintenant, faut-il encore que je comprennes le fonctionnement de cet Huffman :pt1cable:
 
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed