Logiciel de conversion de formats d'image

Signaler
Messages postés
4
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
30 avril 2008
-
Messages postés
4
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
30 avril 2008
-
Bonjour à tous,

Je programme un logiciel de conversion d'images de deux formats différents et j'ai quelques soucis.

Je programme via Visual C++. Je crée une dll pour un logiciel d'image.
Le code ci dessous compile bien mais à l'exécution (dans le logiciel d'image), ça plante (le logiciel se ferme brutalement).

J'ai pu constater (grâce aux traces) que cela se produits à la fin de la boucle while (autrement dit quand on a lu les octets souhaité  - la fin du fichier n'étant pas atteinte).   

//déclaration des variables
    char octet;
    bool run = true;
    int numOctet = 0;
    string  buff, image, header_dm2;
    int dimension, offsetArrayOffset,dataType, width, height, pixelDepth, nbOctetImage;


i = 1;
while (i <= nbOctetImage) {    //nbOctet= 8 388 608
        f_in.read(&amp;octet , 1);
        oct = octet;
        s_octet = getOctetLu(oct);
        image = image + s_octet;
        numOctet++;
        i++;
       //trace
       PlugIn::gResultOut << i << endl;
}


Le problème vient de la ligne
f_in.read(&amp;octet , 1);


En effet pour tester quand j'execute le code ci dessous ca plante:
   f_in.read(&amp;octet , 4000000);


Je comprend vraiment pas ce bug 8O

J'ai aussi un deuxième problème.
Un pixel d'image est représenté par deux octets X1X2X3X4 Y1Y2Y3Y4. Ce sont les valeur hexadécimal.

Le problèmes c'est que dans ce format la valeur de l'octet en hexadécimal est:
Y3Y4Y1Y2 X3X4X1X2  au lieu de X1X2X3X4 Y1Y2Y3Y4.   
Je dois donc octet par octet traiter manuellement cela avant de calculer la valeur en décimal de Y3Y4Y1Y2 X3X4X1X2.
Le problème c'est qu'à l'execution cela va prendre beaucoup trop de temps.

Est-ce que quelqu'un aurait une idée pour résoudre cela?
J'ai aussi vaguement entendu parler de swap data sans comprendre vraiment ce que c'était. Est-ce que cela pourrait résoudre mon problème?

Merci d'avance pour votre aide,
funkyKong

6 réponses

Messages postés
15154
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
19 octobre 2021
99
Salut,
Le 1er problème est simple à comprendre à l'aide du prototype de la fonction:
read(espace mémoire à remplir, nombre d'octets à lire);

Le code suivant fonctionne:
char octet;
f_in.read(&octet,1);

Mais pas celui-ci:
char octet;
f_in.read(&octet,400);

Tu vois pourquoi? Tu essaies de faire rentrer 400 octets dans un espace mémoire qui ne peut en contenir qu'un, d'où plantage... Si tu remplaces la déclaration de octet par: char octet[400], cela marchera mieux

Pour le 2e problème, il n'y a malheureusement pas de recette miracle:
- soit tu peux modifier la représentation d'un pixel et donc tu le mets comme cela t'arrange
- soit tu ne peux pas, donc tu dois faire la conversion à chaque lecture

Cela répond-il à tes questions?

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage
Messages postés
4
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
30 avril 2008

Merci pour ta réponse.

Pour le premier point en effet, c'est une erreur vraiment idiote

Pour le second point, le problème c'est que le traitement octet par octet va prendre trop de temps (ca se compte en heures alors que la conversion doit se dérouler en moins de 10s). Donc je vois pas trop comment faire là .

J'ai aussi un autre problème.

Quand je lis un octet il est un ascii. Je dois donc le convertir en hexa via cette fonction:

// converte un string en un string héxadécimal
string string_hex(string buffer){  
     ostringstream oss; //initialise un string stream qui stock la sortie de std::hex

     //fait une boucle caractére par caractére
     for (string::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
         oss << std::hex << static_cast(*i); //stock la sortie de std::hex dans oss
     }
     return(oss.str());
}

Mais aprés pour un octet, une fois convertit  il y a des caractères en trop. La fonction string_hex est donc buggé mais je vois pas où
Du coup les caractères en trop je les supprime manuellement octet par octet quand je lis le fichier. Si déja je pouvais ne pas avoir de caractères en trop aprés la conversion hexadécimal ca,serait pas mal et réduirais un peu les problèmes
Messages postés
15154
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
19 octobre 2021
99
Ton problème d'inversion est un problème d'endianess. Regarde les fonctions htons() et ntohs().
Par contre, je ne comprends par comment tu fais pour avoir des caractères en trop. Problème de fin de chaine peut-être (il faut un \0 pour terminer un char* )?

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage
Messages postés
4
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
30 avril 2008

Merci !!!!

Je savais déja que c'était un problème d'endianess, mais je savais pas comment le résoudre . Merci je vais alller voir cela

Pour les caractères en trop. Voici une portion de mon code:

string getHexa(char* octet, int nbOctet) {
    string hexa, s;
    string tmp = octet;
    for (int i=0;i<=nbOctet;i++) {
            s = tmp[i];
            hexa = hexa +  string_hex(s);  // avec sting_hex la methode postédans mon précédent post
    }
    return hexa;
}

    int nb = 9;
    f_in.read(octet,nb);
    string hexa = getHexa(octet, nb);
       PlugIn::gResultOut << "hexa => " << hexa << endl;

ca m'affiche :     hexa => 4949ffffff9701100222410000

la chaine en trop est "ffffff"
Il peut il y en  avoir plusieurs à la fois
Messages postés
21
Date d'inscription
mardi 18 janvier 2005
Statut
Membre
Dernière intervention
6 mars 2009

Salut,

Tu dis que tu fais du traitement de caractère mais je trouve ça bizarre pour la lecture d'une image.

Je vois deux possibilité sur le fait que tu recupère de l'ASCII.

1ère possibilité :

    Si tu affiche tes données en utilisant l'operateur "cout" tu aura forcément un caractère car ta donnée est de type char par contre si tu fait un printf("%x", octet) la valeur stockée dans octet sera affiché en hexa juste pour exemple le caractere 'A' vaut 41 en hexa. Tu peux facilement trouver la table ASCII sur un moteur de recherche. Mais ça tu le sais peut être déj.

2ème possibilité :

    Il est aussi possible que tu ouvres ton fichier dans un mauvais mode. Si c'est le fichier image en lui même que tu ouvres, il y a de très forte chance que tu doives l'ouvrir en mode binaire et non en mode texte.

Voila j'espère que ça pourra t'aider.
Messages postés
4
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
30 avril 2008

Salut et merci pour ta réponse,

Non ce n'est bien sur aucune de ces 2 possibilitées.
J'ai résolu tous mes problèmes depuis dimanche dernier.....
J'ai traiter le problème du autre facon en récupérant toutes les info dans un buffer, puis en faisant ensuite le traitement à partir de ce buffer.