IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Conversion héxadécimale étrange


Sujet :

avec Java

  1. #1
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut Conversion héxadécimale étrange
    Bonjour à tous !

    Je suis en train de m'initier à la programmation OpenGL en Java et je suis en train de coder une classe qui me permet de charger une image, d'en extraire la longueur / hauteur et qui stocke une suite d'octets représentants les couleurs RGB (un byte pour chaque couleur) avec un byte pour Alpha si approprié.

    Je m'occupe pour l'instant de charger les fichiers .tga, et ça fonctionnait bien quand je chargeais des fichiers de 256x256. Mais j'ai essayé avec un fichier de 128x128 et ça foire bien comme il faut.
    Il y a une contradiction entre ce que je lis avec un éditeur héxadécimal et l'interprétation de "java".



    En gros j'ai un tableau de byte[] que je remplis avec les données du header du fichier.

    Pour avoir la longueur je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    width = header[1] * 256 + header[0];
    Ce me permet repasser en décimal.

    Mon éditeur héxa (je lui ai demande de m'afficher directement la valeur décimale) me dit : header[1] = 1 et header[0] = 0 (En héxa, il me dit 00 01)

    En début j'ai bien header[1] = 1 et header[0] = 0

    Ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    width = 1 * 256 + 0 = 256
    Pour un fichier qui fait 128 pixels de long, je vois header[1] = 0 et header[0] = 128 dans l'éditeur héxadécimal (soit 00 80 en héxa), mais là, pour une raison qui m'est inconnue, le débugger m'affiche header[0] = -128 et header[1] = 0

    Une fois dans la formule (juste pour le fun), ça fait :
    Soit une longueur de -128 pixels.


    Savez-vous pourquoi Java me sort un nombre négatif de son chapeau ?

  2. #2
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 572
    Points : 15 539
    Points
    15 539
    Par défaut
    Le problème vient de là
    width = header[1] * 256 + header[0];
    Dans les langages comme le C la facon de stoque les nombre de plusieurs octets varie en fonction du type de processeur.
    - Les processeur de type PowerPC(Motorola,IBM,...) sont Big Endian : les octets de poids fort sont en premier. Le nombre 0x123456789 est stoqué en mémoire sous la forme 0x12, 0x34, 0x56, 0x78
    - Les processeur de type x86(Intel, AMD, ...) sont Little Endian : les octets de poids fort sont en dernier. Le nombre 0x123456789 est stoqué en mémoire sous la forme 0x78, 0x56, 0x34, 0x12

    Comme java se doit de tourner de manière identique sous tout les processeur, il a été décider d'utiliser systématiquement le Big endian quel que soit le type de processeur.

    Il te faut donc faire
    width = header[0] * 256 + header[1];

  3. #3
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    Oui mais si j'inverse header[0) et header[1] j'explose tout.

    Si j'inverse :

    Pour 256x256 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    width = 0 * 256 + 1 = 1
    Pour 128x128 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    width = -128 * 256 + 0 = -32768
    Ce qui m'étonne juste c'est que Java interprète 80 en héxa comme étant -128 en décimal, c'est complètement illogique. Y'a forcément un truc qui cloche quelque part !

  4. #4
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 572
    Points : 15 539
    Points
    15 539
    Par défaut
    En fait j'ai dis une bêtise. Etant donné que tu lis un fichier écris en little endian, cela n'a probablement pas d'influence.

    Par contre quel est le type de ta variable width? Il y a des chances que tu aie simplement eu un dépassement de capacité.

  5. #5
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    Width est de type int, mais ce n'est pas ça qui pose problème.

    Dans le débugger j'accède à mon tableau de byte header[] et je constate directement que header[0] = - 128 même avant que le calcul de width soit effectué.

  6. #6
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 572
    Points : 15 539
    Points
    15 539
    Par défaut
    Ce qui m'étonne juste c'est que Java interprète 80 en héxa comme étant -128 en décimal, c'est complètement illogique. Y'a forcément un truc qui cloche quelque part !
    Non c'est tout a fait normal, c'est ce qu'on appelle le complément a 2.

    Par exemple pour un byte (1 octet, code les nombres de -128 à 127)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    codage        |0x00|0x01|...|0x79|0x80|0x81|...|0xFE|0xFF|
    ==========================================================
    signification |   0|   1|...| 127|-128|-127|...|  -2|  -1|
    Cela permet au processeur de traiter les additions et les soustraction sur les nombres signé de manière plus efficace. C'est ce qui de loin le plus utilisé par les processeur pour gérer les nombre signés.
    En java les nombres sont toujours en complément a 2 (sauf les char), alors que en C par exemple on peut utiliser le modificateurs unsigned/signed.

  7. #7
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    En effet...

    Comment faire pour qu'il l'interprète comme étant non signé du coup ?

  8. #8
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 572
    Points : 15 539
    Points
    15 539
    Par défaut
    edit: grosse erreur

  9. #9
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 572
    Points : 15 539
    Points
    15 539
    Par défaut
    Heu je viens de me rendre compte que j'ai encore dit une bêtise c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    width = (header[0]<<8) | (header[1]&0xFF);

  10. #10
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    C'est bien ça !

    Merci pour ton aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Conversion string vers float - résultat étrange
    Par polysil dans le forum Langage
    Réponses: 2
    Dernier message: 18/06/2013, 14h59
  2. Conversion double -> int, problème étrange
    Par mickael9 dans le forum C++
    Réponses: 10
    Dernier message: 20/10/2008, 03h48
  3. Conversion héxadécimale
    Par pierre.coudert dans le forum Langage
    Réponses: 2
    Dernier message: 19/01/2007, 10h23
  4. conversion décimale -> héxadécimale
    Par cout dans le forum C
    Réponses: 6
    Dernier message: 03/07/2006, 14h51
  5. Conversion avec trang
    Par Linaa dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 31/03/2006, 13h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo