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

C++ Discussion :

[c++] Programmation d'un logiciel d'images et gestion des fichiers


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut [c++] Programmation d'un logiciel d'images et gestion des fichiers
    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).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //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;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    i = 1;
    while (i <= nbOctetImage) {    //nbOctet= 8 388 608
            f_in.read(&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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    f_in.read(&octet , 1);
    En effet pour tester quand j'execute le code ci dessous ca plante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       f_in.read(&octet , 4000000);
    Je comprend vraiment pas ce bug







    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

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Tu as oublié d'indiquer le type de f_in, mais c'est tout-à-fait normal que ça plante: Tu as de la place pour un seul octets, et tu essaies d'y en mettre 4 000 000, donc forcément, ça déborde...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut
    Merci pour ta réponse Médonoc

    Voici la déclaration de f_in:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	//fichier en flux d'entrée.
    	ifstream f_in  (nomFichier,ios::binary | ios::in);

    Cependant je ne vois pas trop le problème

    quand je fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     f_in.read(&octet , 10);
    ca marche parfaitement (on lit bien plus que 1 octet là)

    c'est bien dans cette boucle que ca plante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    while (i <= nbOctetImage) {    //nbOctet= 8 388 608
            f_in.read(&octet , 1);
            oct = octet;
            s_octet = getOctetLu(oct);
            image = image + s_octet;
            numOctet++;
            i++;
           //trace
           PlugIn::gResultOut << i << endl;
    }
    et là on lit bien un octet par un octet


    Donc je comprend pas trop

  4. #4
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Tu as oublié d'indiquer le type de f_in, mais c'est tout-à-fait normal que ça plante: Tu as de la place pour un seul octets, et tu essaies d'y en mettre 4 000 000, donc forcément, ça déborde...
    ben oui forcément, ca dépend ca dépasse!!!

  5. #5
    screetch
    Invité(e)
    Par défaut
    pour en revenir au sujet, le fait que ca ne plante pas ne veut pas dire que ca marche. ca veut juste dire que tu as du bol. et des fois on a du bol avec 10 octets, mais avec 4 miyons c'est plus du bol, il faut jouer au loto. si tu arrives a faire rentrer 4 miyons d'octets dans un seul je te felicite, tu as trouvé la methode de compression la plus efficace au monde.

    reserve de la place pour un octet.
    reserve de la place pour 1024 octets.

    a toi de savoir combien tu en veux (4 miyons ca ne tiendra pas dans une variable locale) mais 1 seul ce n'est pas assez d'espace.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut
    En fait je croyait qu'a chaque fois qu'il bouclait, il allait ecraser la valeur précédente.


    effectivement c'est logique. J'ai honte

    En tout cas Merci à tout les deux

    En fait il faut que j'en réserve 10 000 000 de places

    Sinon personne a une idée concernant mon deuxième problème (expliqué à mon premier post ci-dessus) ?

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Tu sais, tu peux utiliser la fonction membre ignore() si tu veux "sauter" des octets...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre chevronné Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Par défaut
    Pour ton deuxième problème, es-tu sûr que ta conversion va prendre énormément de temps de calcul en plus?

    Quel est la taille de tes images?
    Combien en as-tu à traiter, dans quel limite de temps?

    Est-ce qu'une optimisation est nécessaire?

    Peut-être que ta solution est déja suffissante...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut
    Merci je me deplace deja avec un f_in.seekg

    Pour la contrainte de temps je dois faire ca en moins de 10s. En lisant tout d'un coup c'est faisable, mais en lisant octet par octet cela prend dans les 7h30

    Le problème c'est que je dois traiter chaque octet. Pour deux raison:
    1) quand je lit deux octets, dans le premier format ils sont stockés en middle endian (donc quand je lis en hexa ca donne ca: Y3Y4Y2Y1 X3X4X2X1 au lieu de X1X2X3X4 Y1Y2Y3Y4). Je dois donc faire des opérations de conversion sur les bits tous les deux octet
    2) il faut ensuite que je calcul la valeur décimal des deux octet qui sont représenté en hexa.

    Pour la taille de l'image c'est dans la dizaine de Mo pour le moment.

  10. #10
    Membre chevronné Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Par défaut
    Pour la contrainte de temps je dois faire ca en moins de 10s. En lisant tout d'un coup c'est faisable, mais en lisant octet par octet cela prend dans les 7h30
    7h30 pour 10 mega de données !! c'est vraiment impréssionnant.
    et même les 10s ça à l'air gros pour charger un fichier.

    Soit tu as un gros soucie dans ton algo, soit tu tournes sur une machine des années 60...
    Plus sérieusement, peut-être que lire octet par octet n'est pas une bonne solution (l'OS doit être trop sollicité)

    Et si tu essayais de charger entiérement le fichier dans un buffer pour ensuite y faire les traitements.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut
    oui j'avais pensais à cela mais je sais pas si il y aura une si grande différence de temps.

    Sinon quand je dit 10 secondes ca doit comprendre la lecture du fichier, le traitement de tous les octets et l'écriture dans un autre fichiers.

    Pour l'idée du buffer je verrais demain ce qu'il en est

  12. #12
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    En fait, il y a plusieurs problêmes:

    - Problême de lecture du fichier.

    Les streams C++ sont l'interface la plus lente. Les FILE descriptor du C ne sont guère mieux, juste un poil. Le plus rapide va dépendre de ton système (comme toujours), et s'adapter à la taille de la source (par exemple un cluster du disque).

    Ce qui est sur, c'est que lire octet par octet est la pire des choses à faire... A chaque lecture, le code va faire des tests, vérifier qu'il n'y a pas à faire un accès disque, bref... tout un tas de tralala complètement inadapté à la lecture d'un tout petit fichier de 10Mo (pour info, un fichier de 10Mo se convertissait en 2 minutes entre JPG et IVUE/FlashPix par exemple sur un 486dx100 avec windows 3.1).

    10Mo c'est même pas la taille mémoire occupée par le logon de windows maintenant !!! Donc: Lis *TOUT* ton fichier d'un coup. Si vraiment il n'y a pas moyen d'allouer 10Mo en mémoire, autant dire le systeme est HS.

    Si vraiment tu ne peux pas (fichier > 50Mo ou 100Mo par exemple), alors lis par groupe de donnée... genre 16Mo par 16Mo.


    - Problême de traitement d'image, en l'occurence remise en ordre des pixels (transformation des pixel-formats).

    C'est un problême assez simple, quoique tu nous en dise pas beaucoup... Je ne connais pas beaucoup de formats d'image ou les pixels ont un endianness... A moins de travailler sur un format >32 bits. Donc ma question est... quel pixel-format as tu en entrée, et quel pixel-format veux tu en sortie ?
    Les deux pixel-formats les plus utilisés sont: A_R_G_B (le plus classique) et R_G_B_A.

    Là encore, le traitement s'optimise en fonction des pages de cache-data (en général 64 octets), donc, traite 64 octets par 64 octets.
    Pour information, dérouler le traitement (traiter 4 pixels par 4 pixels par exemple) aide énormément (2 cycles de test à chaque boucle, 6 cycles de traitement par pixel => 32 cycles sans dérouler, 26 cycles en déroulant).

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut
    Salut,

    En fait je dois convertir des fichiers en ".ser" en ".dm3". Par contre je ne connais pas les pixel formats de mes deux images (les images en .ser sont impossible à ouvrir hors éditeur héxadecimal).

    Par contre il y a un autre problème dont je n'avais pas pensé hier soir. Lorsque je lit un octet il y a plein de caractères "en trop" derrière l' octet .
    Je récupérais donc chaque octets séparement pour pouvoir traiter ce cas:
    - d'abord récupérer les deux premier caractéres (ce qui correspond à l'octet) sans les caractère en trop.
    - ensuite si la valeur héxa de l'octet est inferieur à $10 alors je n'ai qu'un caractère (0 ou 1 ou 2 ou....9) au lieu d'avoir un 0 devant. Je dois donc le rajouté manuellement.
    - enfin il y a un cas spécial où cette chaine "fffffff7" vient se mettre devant les deux caractères de l'octet

    J'avais crée une méthode pour traiter ce problème mais ca m'oblige à lire le fichier octet par octet.

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Euh... Comment peux-tu convertir si tu ne connais pas le format ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut
    Je connais bien la structure des formats des images (j'ai du analyser tout cela via un éditeur hexadécimal), mais c'est juste que je n'ai aucune idée du format des pixel.

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut
    Quand je lis le fichier d'un coup, cela me prend moins de 3s.

    Par contre aprés quand je veux lire le buffer octet par octet il me faut 22h (je lit 10000 octet en 8s soit 8388608 octet en 22h). C'est encore pire que par la lecture de fichier 1 octet par un octet
    Et encore c'est sans avoir reglé le problèmes de caractères en trop et bizarre



    Pour les pixel formats:
    Un pixel est selon les cas soit sur 1,2,4,8 ou 16 octets (16 pour les images complexe).
    Bon dans le premier cas un pixel est sur 2 octets.

    Le format du pixel d'entrée (pour l'image au format .ser) est le middle endian et le format du pixel de sortie est le little endian (pour l'image au format .dm3).

  17. #17
    Membre chevronné Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Par défaut
    Je connais bien la structure des formats des images (j'ai du analyser tout cela via un éditeur hexadécimal), mais c'est juste que je n'ai aucune idée du format des pixel.
    Tu connais la structure des images, mais pas le format des pixels...
    Tes images sont composées de quoi alors ?

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 49
    Par défaut
    en fait qu'entend tu par format des pixel? Parce que dans mon précedent post, j'avais répondu ca :

    Pour les pixel formats:
    Un pixel est selon les cas soit sur 1,2,4,8 ou 16 octets (16 pour les images complexe).
    Bon dans le premier cas un pixel est sur 2 octets.

    Le format du pixel d'entrée (pour l'image au format .ser) est le middle endian et le format du pixel de sortie est le little endian (pour l'image au format .dm3).

    Pour les caractères en trop je pense que j'ai compris d'où ca vient. Quand je lis dans le fichier, je lis malheuresement des ascii. Je dois donc les convertir en hexadecimal via cette fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 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<int>(*i); //stock la sortie de std::hex dans oss
         }
         return(oss.str());
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    Cette fonction doit être buggé mais où

  19. #19
    Membre chevronné Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Par défaut
    Oulalalala... mais dans quoi tu t'ai embarqué!
    Je commence à comprendre pourquoi ça te prends 37h pour charger une image...

    Si je peux de donner un conseille, oublis les strings et la STL pour convertir tes images.

    Utilise tout simplement le type char, qui est parfait pour manipuler les octets puisque sizeof(char) = 1.

    en fait qu'entend tu par format des pixel? Parce que dans mon précedent post, j'avais répondu ca :
    format des pixel:

    comment les composantes des couleurs sont elles organisée ?

    Généralement les pixels sont codées sur 24 bit, 8 bits par composantes (Rouge, Vert ou Bleu) + 8 bits si tu gére un canal alpha pour la transparence... ce qui nous fait un maximum de 32 bits soit 4 octets.

    Ensuite dans quelles ordres elles sont placées : RGBA, ARGB ...

    Un pixel est selon les cas soit sur 1,2,4,8 ou 16 octets (16 pour les images complexe)
    8 ou 16 octets, ça me paraît beaucoup pour coder 1 pixel. Qu'est ce qu'on peut bien mettre dans 16 octet ?

  20. #20
    screetch
    Invité(e)
    Par défaut
    4 floats.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Recherche logiciel programmation analyse video/reconnaissance d'image
    Par MoneyCivius dans le forum Logiciels Libres & Open Source
    Réponses: 0
    Dernier message: 10/09/2014, 10h15
  2. [MySQL] Création de dossiers pour stocker des images et gestion des droits
    Par heretik25 dans le forum PHP & Base de données
    Réponses: 17
    Dernier message: 14/12/2011, 10h24
  3. Réponses: 1
    Dernier message: 07/04/2009, 00h18
  4. [MySQL] Programmation Objet PHP-Mysql - Comment formaliser la gestion des listes
    Par bacchus41 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 04/04/2009, 21h33
  5. Recherche d'un SGBG pour la gestion des fichiers images !
    Par PandaConstantin01 dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 04/09/2006, 13h53

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