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 :

Ajout de tableau à la fin d'un tableau


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 87
    Par défaut Ajout de tableau à la fin d'un tableau
    Bonjour j'utilise memcpy() pour copier un tableau dans un autre, no probleme.

    Mais là j'ai un tableau A d'une taille égale à disons 10 fois un tableau B.
    Je veux copier 10 fois le tableau B dans A car B change de valeur. Je ne souhaite pas parcourir 10 fois mon tableau B mais faire 10 copie succesive de B vers A et au bon endroit dans A (bout à bout avec décalage de la taille de B).

    Comment dois-je procéder si cela est possible?

    Merci

  2. #2
    Membre expérimenté Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Par défaut
    Une petite copie de B sur A, puis 9 memcpy de A[ debut + i*taille de B] vers A[ debut + (i+1) * taille de B ]

    Ca me parait jouable.

    Tiens, encore mieux, mais a tester parceque je sais pas si ça marche :

    Copie de B sur A, puis un seul memcpy de A vers A + taille de B, sur 9 * taille de B octets.

  3. #3
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par TobyKaos Voir le message
    Mais là j'ai un tableau A d'une taille égale à disons 10 fois un tableau B.
    Je veux copier 10 fois le tableau B dans A car B change de valeur. Je ne souhaite pas parcourir 10 fois mon tableau B mais faire 10 copie succesive de B vers A et au bon endroit dans A (bout à bout avec décalage de la taille de B).

    Comment dois-je procéder si cela est possible?
    memcpy() avec les bons offsets... Evidemment, le tableau de destination doit être suffisamment grand...

  4. #4
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Juste une question de calcul, avec quoi mettre dans memcpy.
    Bon algo.

  5. #5
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 87
    Par défaut
    J'ai essayé en modifiant mon l'offset du tableau de destination mais j'obtiens n'importe quoi:

    Voici mon pseudo code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Entrée: uint8* allData
    offset = 0;
    dataSize
     
     Pour toutes lignes
        Pour toutes colonnes
     
            memcpy(allData+(dataSize*offset), (uint8*)(getData(row, col)), sizeof(uint8)*dataSize);
            offset++
        Fin Pour
     Fin Pour
    getData me renvoie les données en uint8*

    J'ai essayé avec memmove et j'obtiens aussi n'importe quoi.

    Je ne renvoie pas mon allData car il est passé en parametre et donc modifier dans la fonction.

    Petite précision cela marche si je fais cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
     
    Entrée: 
    uint8* allData
    Struct pixel
    {
      int x,y;
      uint8[3] pixelValue;
    }
    n=0;
     
    Pour chaque Lignes
       Pour chaque colonnes
           getPixelValue(pixel)
     
          Pour chaque valeur RGB i
            allData[n] = pixel.pixelValue[i];
            n++;
         Fin pour
       Fin Pour
    Fin pour
    Cela marche bien mais est très lent car le getPixelValue fait pas mal de calculs.


    Et si je fais un mix des deux soutions en faisant un memcpy dans un tableau temporaire puis que je le parcours pour recopier chaque valeurs j'obtiens n'importe quoi.

    Il y a quelque chose qui m'échappe. Je ne vois pas quoi.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Euh !!!

    Faudrait d'abord voir à utiliser les bons termes..

    Tu dis :

    Entrée: uint8* allData
    mais c'est dedans que tu écris.... C'est pas plutôt une sortie, ça ????

    Ensuite, quel est le format de ton fichier ?? ça ressemble un peu à du Gif, ou ppm..

    Es-tu sûr que ta fonction GetData(row,col) fais le travail ??? Je ne vois pas en quoi (vu que tu passes un pixel : row,col, et non une ligne) elle devrait être différente de GetPixel...

  7. #7
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 87
    Par défaut
    Merci pour ton intérêt à ma question.

    Non je ne me trompe pas de terme, je passe en entrée de ma fonction mon pointeur uint8* allData et ma fonction renvoie void car elle affecte directement mon allData. C'est comme cela que je fais avec la solution qui marche bien mais qui est lente.

    Mon format est du tif tuilé. Pour faire simple je stocke une partie de mon image dans un contener vector de vector de tuile. jai donc chargé mes tuiles disons x=10 a 20 et y= 20 a 30. dans mon contener[10][10] du coup.

    le getPixelValue va donc pour un pixel donné (x=1000, y=10000) calculer a quel tuile on doit demander la valeur RGB du pixel.
    Ceci est long en calcul.

    Donc au lieu de parcourir tous les pixels je parcours seulement les tuiles et getData me renvoie tout le buffer d'une tuile que je copie dans mon allData et au bon endroit.

    Je ne voulais pas en arriver à rentrer dans les détails mon bon.

    Si cela peut aider sur ma réflexion, merci.

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par TobyKaos Voir le message
    ...Non je ne me trompe pas de terme, je passe en entrée de ma fonction mon pointeur uint8* allData et ma fonction renvoie void car elle affecte directement mon allData. C'est comme cela que je fais avec la solution qui marche bien mais qui est lente.
    ...
    Disons que ton pointeur est en entrée mais c'est là où tu places ton résultalt, c'est donc une sortie.

    De plus, pour faire de la bonne programmation (ce qui homogénéiserait les notions), il serait plus sain que ce soit cette routine qui alloue la place, et affecte juste le pointeur... (ce qui en ferait réellement une sortie).

    Maintenant quant au problème de fond, je réitère ma question :

    Es-tu sûr que ton GetData fais bien ce qu'il doit faire ?
    Parce que pour le GetPixel, tu lis 3 valeurs, donc pour ton GetData tu les lis bien aussi ?? (donc la dimension serait sans doute 3*tileX*TileY)

    D'autre part, dans ton pseudo algo, ya un truc qui cloche...

    Tu fais pour le GetPixel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Pour chaque Lignes
       Pour chaque colonnes
         ........
       Fin pour
    Fin pour
    mais tu fais pour GetData :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     Pour toutes lignes
        Pour toutes colonnes
        ......
        Fin Pour
     Fin Pour
    Ya pas quelque chose qui te choque là dedans ??

    Ca devrait être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     Pour toutes lignes par pas de hauteur de tuile
        Pour toutes colonnes par pas de largeur de tuile
        ......
        Fin Pour
     Fin Pour

  9. #9
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 87
    Par défaut
    J'ai essayé de faire en sorte que ce soit ma fonction qui alloue la memoire a allData mais en vain(meme résultat une image bizarre)

    Mon dataSize est égal à largeurTuile*hauteurTuile*nbCouleur soit 240*240*3

    getData me renvoie le buffer d'une tuile qui fait 240*240*3

    Mon tableau fait largeurTotal*hauteurTotal*nbCouleur soit ici 7440*2640*3

    Sinon tu as raison pour la dernière boucle, c'est ce que je fais.

    Et donc pour moi mon algo et mes données sont bonnes sauf qu'à la fin j'obtiens une image qui est pleine d'artefact.
    J'ai pensé que cela pouvait venir d'un problème de conversion de donnée. Mais je vois pas trop où.

    Et de plus avec la méthode lente cela marche bien.

    Sinon tanpis je suis pas à 5 minutes ce n'est pas du temps réel.

  10. #10
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Poste le code....

  11. #11
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 87
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    void IM_Page::getAllData(uint8* allData)
    {
     
       unsigned int dtx,dty,ftx,fty;
        dtx = (unsigned short int)floor(currentReadBox.XTop/(float)tiffP.componentWidth);
        ftx = (unsigned short int)ceil(currentReadBox.XBtm/(float)tiffP.componentWidth);
        dty = (unsigned short int)floor(currentReadBox.YTop/(float)tiffP.componentHeight);
        fty = (unsigned short int)ceil(currentReadBox.YBtm/(float)tiffP.componentHeight);
     
        unsigned int row, col;
        int dataSize = tiffP.componentWidth*tiffP.componentHeight*tiffP.colorMode;
        int offset=0;
     
        for(row=0; row < fty - dty; row++)
        {
          for(col=0; col <  ftx - dtx; col++)
          {
             memcpy(allData+(dataSize*offset), (uint8*)(getData(row, col)), sizeof(uint8)*dataSize);
            offset++;
          }
     
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     uint8* IM_Page::getData(unsigned int row, unsigned int col)
      {
        return container[row][col]->getData();
      }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      public:
        virtual uint8* getData(){return buffer; };
      protected:
        uint8* buffer;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
       uint8* allData;
        unsigned int widthData  = (unsigned int)floor(vPages[currentPage]->getCurrentReadBoxWidth());
        unsigned int heightData = (unsigned int)floor(vPages[currentPage]->getCurrentReadBoxHeight());
        unsigned int colorMode  = vPages[currentPage]->getColorMode();
         if((allData=(uint8*)malloc(widthData*heightData*colorMode*sizeof(uint8))) == NULL) {
          throw IM_OutOfMemory(__FILE__, __LINE__,"Allocation failed");
        }
        IM_ImageMemory ims(widthData, heightData, colorMode);
        vPages[currentPage]->getAllData(allData);
        ims.fromData(allData);
     
       // .....
       // mes traitements...
       // ....
     
     
        free(allData);

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par TobyKaos Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void IM_Page::getAllData(uint8* allData)
    Pas du C. Le C++, c'est à coté.

  13. #13
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 87
    Par défaut
    Mais lol, j'ai posté dans le C++, le modo à déplacé mon message dans le forum C. Et faut que je redéplace dans le C++ ?

    Le problème viens du memcopy

  14. #14
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ne connaissant rien au C++, je ne peux guère comprendre le code ci-dessus, mais je réitère ma remarque précédente :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        for(row=0; row < fty - dty; row++)
        {
          for(col=0; col <  ftx - dtx; col++)
          {
             memcpy(allData+(dataSize*offset), (uint8*)(getData(row, col)), sizeof(uint8)*dataSize);
            offset++;
          }
     
        }
    Il me semble qu'au lieu des row++ et col++ ce devrait être row+hauteur_tuile, col+largeur_tuile....

  15. #15
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par TobyKaos Voir le message
    Le problème viens du memcopy
    Y'a pas de memcopy() en C.

  16. #16
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 87
    Par défaut
    Ha ok, puisqu'il n'y a pas de memcpy en C est ce qu'on renvoie mon topic sur le forum C++ (ping pong)

    @Souviron34:
    dtx = la première tuile en X
    dty = la première tuile en Y
    ftx = la dernière tuile en X
    fty = la dernière tuile en Y

    Et donc je parcours bien mes tuiles. Et je copie à l'emplacement mémoire de allData de la taille d'une tuile * nbTuile soit dataSize*offset

    En tout cas merci quand même de vous en intéressé.

  17. #17
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par TobyKaos Voir le message
    Ha ok, puisqu'il n'y a pas de memcpy en C
    Si, il y a memcpy() en C. C'est memcopy() qui est inconnue... Il faut être précis...

  18. #18
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par TobyKaos Voir le message
    ...
    Et donc je parcours bien mes tuiles.
    ...
    TU NE LIS PAS CE QU'ON ECRIT :

    Il me semble qu'au lieu des row++ et col++ ce devrait être row+hauteur_tuile, col+largeur_tuile....
    Je n'ai pas parlé des TERMINAISONS, mais des INCREMENTS..

  19. #19
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 87
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    TU NE LIS PAS CE QU'ON ECRIT :

    Je n'ai pas parlé des TERMINAISONS, mais des INCREMENTS..
    Hum, bien sur que je lis ce que tu as écris.

    Je réexplique. J'incrément de 1 car je parcours tuile par tuile et non pixel par pixel. la fonction getData(row, col) récupère le buffer (de taille dataSize = hauteurTuile*largeurTuile*nbCouleur) de la tuile row, col.
    Ensuite je copie ce buffer via MEMCPY dans le tableau allData en faisant varier l'adresse mémoire de offset*dataSize ou offset est incrémenté de 1 à chaque tour. Soit pour
    row=0, col=0 0*largeurTuile*hauteurTuile*nbCouleur.
    Puis pour row=0, col=1: 1*largeurTuile*hauteurTuile*nbCouleur.
    row=0, col=2: 2*largeurTuile*hauteurTuile*nbCouleur.
    row=1, col=0: 3*largeurTuile*hauteurTuile*nbCouleur.
    ....

    Je ne comprends pas pourquoi la copie ne fonctionne pas bien. le problème vient il du décalage allData+(dataSize*offset) ?

  20. #20
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Reprenons calmement..

    Je crois (si je comprend, ce qui n'est pas sûr vu que c'est pas du C), que tu te mélanges les pinceaux...

    Est-ce que l'instruction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       return container[row][col]->getData();
    renvoie bien une TUILE ?

    Quand tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        for(row=0; row < fty - dty; row++)
        {
          for(col=0; col <  ftx - dtx; col++)
          {
             memcpy(allData+(dataSize*offset), (uint8*)(getData(row, col)), sizeof(uint8)*dataSize);
            offset++;
          }
    tu vas chercher ce qui est d'abord en (0,0), puis en (0,1), puis en (0,2), etc etc..

    C'est bien ça que tu veux ??

    D'autre part, tes calculs de départ me paraissent louches :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        ftx = (unsigned short int)ceil(currentReadBox.XBtm/(float)tiffP.componentWidth);
    ne te donnera pas le nombre de pas... Par contre,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        ftx = (unsigned short int)ceil((currentReadBox.XBtm - CurrentReadBox.XTop)/(float)tiffP.componentWidth);
    oui

    et ainsi de suite....

Discussions similaires

  1. ajouter à la fin d'un tableau de cellules
    Par syki.mail dans le forum MATLAB
    Réponses: 3
    Dernier message: 26/01/2014, 10h15
  2. ajouter un élément à la fin d'un tableau [[],[],[]]
    Par wise_mind dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 12/06/2009, 16h01
  3. Réponses: 13
    Dernier message: 01/02/2006, 12h00
  4. Réponses: 4
    Dernier message: 27/10/2005, 10h09
  5. Ajout de ligne à la volée dans un tableau
    Par Folken Laëneck dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 22/08/2005, 11h41

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