Problème de type: Pixel =int, char ? - C - Programmation
Marsh Posté le 04-04-2007 à 13:24:40
Bonjour,
La question n'est pas très claire, parce qu'elle manque d'exemples, et parce que le vocabulaire ne parait pas très bien choisi.
Qu'est-ce qu'un pixel pour vous ? Théoriquement, c'est un point lumineux. Mais dans votre question, il semble que vous emplyer ce mot au lieu de "un charactère imprimable contenant une valeur booléenne". Putchar(), fwrite() ne vous doneront jamais de points lumineux. Il vous donneront des charactères. Quelle valeur booléenne voulez-vous obtenir ? Si vous voulez "0xFE", alors ce n'est pas un caractère imprimable et vous aurez un point d'interrogation à la place.
Si je ne me trompe pas, je devine que vous voulez faire les transformations suivantes :
Entrée Sortie
0 --> "00000000" = 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
1 --> "00000001" = 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,
2 --> "00000010" = 0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x30,
3 --> "00000011" = 0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,
...
255 --> 11111111
En entré ce serait un unsigned char, et en sortie ce serait 8 char ou 8 unsigned char contenant soit "0", soit "1".
Pour infos, le code pour "0" est 0x30. Le code pour "1" est 0x31.
Est-ce que j'ai bien compris la question et est-ce que vous voyez la solution ?
Marsh Posté le 05-04-2007 à 09:50:47
Les Pixels sont lus avec fread, et récupérés dans des unsigned char.
Ces sur ces unsigned char que je dois faire les opérations (quelques masquages)
Ensuite je veux les récrire avec fread.
Or, bien que ce soit des unsigned char, je constate que putchar affiche des caractères non-imprimables -> 1er point obscur.
2éme point obscur: si je les affiche en tant que 'int' (avec un printf("%d" ) ), alors j'ai tout un ensemble de nombres qui me permettent de vérifier que mes opérations de masquages marchent bien.
Par contre, quand j'affiche le contenu de l'image avec la commande linux od -c img.pgm, la je constate que ces chiffres ne sont plus les mêmes !!! (comme si fwrite les avait changés)
PS: chaque Pixel (unsigned char p) suit l'opération suivante:
- p_old = p & 0xFE ( je sauvegarde les 7 premiers bits sauf le dernier)
- p=p_old | 0x01 (pour lui mettre le bit poid faible à 1 suivant la lettre à coder)
OU p=p_old | 0x00 (pour lui mettre le bit poid faible à zéro suivant...)
Marsh Posté le 05-04-2007 à 10:10:43
char , en C , c'est juste la taille des données , donc il est logique que tu ai des caractères non affichables , ou meme des bip . il n'y a pas de contrainte disant qu'un char doit etre un caractère affichable
pour la suite, je ne sais psa
Marsh Posté le 05-04-2007 à 10:35:35
Poste nous ton code (la partie intéressante), comme ça on saura exactement ce que tu as fait (ce sera plus simple que de tenter de l'expliquer avec des mots)
Sinon, je ne sais pas trop ce que donne un printf("%d" ) avec un unsigned char. C'est peut-être simplement là que se situe ton problème...
Marsh Posté le 05-04-2007 à 11:23:58
cambronne3 a écrit : 1/ Si je fais putchar(c), j'ai systématiquement un point d'interrogation... |
Normal, si la valeur que tu envoies à "putchar()" n'est pas celle d'un code ascii affichable (voir pour ça les fonctions "isprint()", "isascii()" et autres...) ben le terminal affiche ce qu'il peut...
cambronne3 a écrit : 2/ Si j'affiche en tant que "int" j'ai certains nombres dans mon tableau. Donc la je fais un fwrite pour tout reécrire dans une image (image codée), mais les valeurs des pixels (que j'affiche avec od -c image.pgm) ne correspondent pas à celle du tableau. |
De quelle façon affiches-tu ? "%d" ?? "%u" ??? "%x" ???
cambronne3 a écrit : Quelqu'un peut-il m'expliquer comment ca se passe réellement ? J'ai l'impression que le type char pose problème et je comprend pas trop... |
Non, ce qui pose problème c'est la façon dont tu vérifies tes infos. Faut bien comprendre qu'un nombre codé en mémoire ne signifie pas la même chose selon qu'il soit int, double, signé, non-signé. Et "printf()" fait ce qu'il peut avec les infos qu'on lui donne. Par exemple, tu écrits
printf("%u", -1) |
Ben (sauf erreur de ma part car je réponds au jugé) tu auras 65535 parce que, en binaire sur 16 bits non signés, 65535 se code "1111111111111111" alors que "-1" sur 16 bits signés se code "1111111111111111". Ainsi "printf()" recevant une valeur et toi lui demandant de l'afficher en non-signé, il l'affiche en non-signé.
Ce genre d'erreur (zut, je n'obtiens pas à l'écran ce que j'imagine avoir dans ma variable) est fréquent quand on mélange à la fois les types des variables et les ordres d'affichage donnés à "printf()".
Donc commence par bien poser tes types. Si tu travailles en non-signé c'est à dire si tu n'as pas besoin de réserver un bit pour le signe (ce qui est le cas avec la forme de stockage d'un pixel qui code chaque canal RVB sur un octet entier) alors déclare tes valeurs en "unsigned". En plus, coder en signé alors qu'on travaille en non-signé peut produire des effets de bords. Ex:
signed char a
unsigned int b
a=128 (soit 1000000 en binaire)
b=a
Tu espères avoir "b=128" alors que t'auras (sauf erreur) "b=65408". Pourquoi ? Parce que "a" est considéré comme signé et que le signe est conservé donc le premier bit est recopié sur toute la zone située à gauche quand "a" est copié dans "b" (ça donne 1111 1111 1000 0000 en binaire).
Ensuite, quand tu donnes un format à "printf()", respecte bien le format du nombre que tu fournis.
Alors seulement là t'auras correspondance entre tes calculs et ce que tu vois à l'écran...
franceso a écrit : Sinon, je ne sais pas trop ce que donne un printf("%d" ) avec un unsigned char. |
Un "unsigned char" étant un nombre pouvant aller de 0 à 255, le printf() affichera simplement ce nombre
Marsh Posté le 05-04-2007 à 11:46:37
Au temps pour moi
Il me semblait qu'il y avait des problèmes de ce genre (en particulier avec les signes), mais je supose que ça ne concerne que les signed char.
Marsh Posté le 05-04-2007 à 11:47:59
franceso a écrit : Au temps pour moi |
J'ai modifié mon post précédent et cela devrait répondre aussi à ta question...
Marsh Posté le 05-04-2007 à 11:58:00
Sve@r a écrit : |
euh, b vaudra 128 la. Promotion entière tout ça ...
ah ben non :| diantre o_O
Marsh Posté le 05-04-2007 à 15:16:27
Je vous remercie tous pour vos explications, en fait la différences entre caractères affichés par printf("%d" ) et "od -c image" vient tout simplement du fait que "od -c" affiche en octal, et qu'aprés conversion j'avais bien le bon affichage...
Marsh Posté le 05-04-2007 à 15:59:47
Joel F a écrit :
|
Hum...
b vaudra 128 si tu déclares "a" comme "unsigned"...
Marsh Posté le 04-04-2007 à 12:44:33
Salut,
Je fais un programme de stéganographie. Je dois donc coder les 8 bits d'un char dans 8 Pixels successfis (en modifiant leur bit de poid faible).
Les Pixels d'image sont stockés dans un tableau de unsigned char.
Je fais plusieurs opérations logiques pour manipuler les bits, par exemple: unsigned char c = caractere & 0xFE;
Et la apparait un problème:
1/ Si je fais putchar(c), j'ai systématiquement un point d'interrogation...
2/ Si j'affiche en tant que "int" j'ai certains nombres dans mon tableau. Donc la je fais un fwrite pour tout reécrire dans une image (image codée), mais les valeurs des pixels (que j'affiche avec od -c image.pgm) ne correspondent pas à celle du tableau.
Quelqu'un peut-il m'expliquer comment ca se passe réellement ? J'ai l'impression que le type char pose problème et je comprend pas trop...
Merci d'avance