Portage logiciel graphique depuis Visual Studio C++

regattaregatta Membre
06:12 modifié dans Vos applications #1
Bonjour,

je recherche des informations pour porter un logiciel de focus stacking (augmentation de la profondeur de champs à  partir d'une pile de photos) depuis windows.
Ce logiciel est disponible sous la licence GNU (combine ZM) et utilise la librairie fftw3.

Voici quelques questions, n'ayant pas l'habite des traitements graphiques :
  • le logiciel source utilise des structures et unions pour mémoriser les éléments des image : faut-il conserver ce mode ou plutôt passer par des classes ?
  • la gestion de nombreuses images fait que le logiciel windows ne gère en mémoire qu'une partie des données et stocke les autres sous forme de fichiers : comment gérer sous mac de grands volumes de données ?

Merci pour vos tuyaux pour partir dans une bonne direction et déterminer si cela est réalisable !

Cordialement
Regatta

Réponses

  • wiskywisky Membre
    06:12 modifié #2
    J'aurais plutôt tendance à  ma poser les questions suivantes :
    Les bibliothèques existe-elle en open source et sur Linux ?
    Le logicielle tourne-il sur linux (sans émulateur) ?

    Le portage sur Mac peux être réalisé en utilisant X11 dans un premier temps.

    Pour répondre à  tes questions, il est possible d'utiliser des structures et union sur mac ainsi que l'utilisation de fichiers pour stocker les données.
  • tabliertablier Membre
    06:12 modifié #3
      :p   D'accord avec wisky!
    Tout ce que tu peux faire en C standard est faisable en Objective-C qui est une extension objet du C.
    Pour X11, je suis moins enthousiaste. Cela reste quand même une solution.
  • regattaregatta Membre
    06:12 modifié #4
    La librairie fftw3 est disponible en open source donc pas de problème pour cela.

    Le programme n'existe pas sur linux donc pas de X11.

    La question sur les structure et union est plus sur la manière optimale de gérer des images et des traitements sur ces images, que sur le fait de pouvoir les utiliser.
    Je pensais à  utiliser des classes de Cocoa à  la place de structure (NSData ?).

    Le code source en Visual Studio n'a que quelques classes de base de windows : xxxDoc, xxxView et les classes pour les fenêtres de dialogue.

    Doit-on utiliser les structures (pour des questions de performance) ou peut on utiliser des classes sans dégrader les performances.

    Pour ce qui est de la gestion mémoire avec beaucoup de données à  traiter (100 images de 2520 * 1920 par exemple) je ne connais aucun exemple expliquant la manière de procédé.

    En espérant être plus clair sur mes questions.
  • tabliertablier Membre
    août 2011 modifié #5
    Là , les spécialistes corrigeront:
    Programmer des traitements en C devrait être plus rapide à  l'exécution que d'utiliser des classes. Pour des cas très particuliers ont peut même remonter à  l'assembleur (parfois très galère!).
    Ensuite, NSData et structures ne sont pas équivalents: une structure est un assemblage défini de variables ou constantes alors que NSData est une classe  dont la zone de stockage de données n'est qu'une suite d'octets sans rôle particulier.

    Pour traiter un grand nombre d'image, les logiciels font souvent ça image par image. Par exemple dans Graphic Converter il y a un traitement d'image par dossier. Le traitement est appliqué à  toutes les images d'un dossier et les résultats sont mis dans un nouveau dossier.
  • laudemalaudema Membre
    06:12 modifié #6
    Peut être que Image Kit a déjà  une partie de la solution : c'est un ensemble de classes pour traiter les images qu'Apple prétend avoir particulièrement optimisées, et il n'y a pas de raisons d'en douter :)

    The Image Kit is an Objective-C framework, introduced in Mac OS X v10.5, for browsing, viewing, editing, and processing images in an efficient manner.


    Anyone developing a digital media application that supports images will want to read this document to find out how to use the Image Kit to provide the best user experience possible. You don't need to be a seasoned Cocoa programmer to use the Image Kit or to read this guide, although prior experience with Objective-C is helpful and will make it easier to understand the code examples.

    my 2 ¢
  • AliGatorAliGator Membre, Modérateur
    06:12 modifié #7
    Sans parler de CoreImage.

    La question n'est pas "est-ce que je dois utiliser les structures" mais "est-ce que j'ai des libs compatibles OSX" voire "est-ce qu'on a pas mieux"
  • regattaregatta Membre
    06:12 modifié #8
    Merci pour ces réponses.

    Je vais regarder ImageKit pour voir ce qu'à  fait Apple.

    Pour les libs compatibles OSX, j'ai compilé fftw3 pour mac (cette librairie est celle utilisée dans la version windows), mais c'est en C.

    Pour des suggestions de librairies compatible OSX, je suis preneur  :)
  • regattaregatta Membre
    06:12 modifié #9
    Pour expliquer le but du logiciel, voici des images obtenues par un autre logiciel du même type
    (mais moins efficace !)

    http://www.heliconsoft.com/animation/Krebs_fly1/index.html

    Toutes les photos sont combinées en une seule, mais avec une bonne profondeur de champ !
  • AliGatorAliGator Membre, Modérateur
    06:12 modifié #10
    A mon avis CoreImage sait déjà  faire la majorité du boulot.
  • CéroceCéroce Membre, Modérateur
    06:12 modifié #11
    Core Image est tout indiqué (et certainement pas Image Kit), par ses performances (CI utilise le CPU et le GPU) et la simplicité relative de sa mise en oe“uvre.
    Par contre, l'utiliser implique de comprendre les algorithmes et de les reprogrammer entièrement, car Core Image utilise un langage dérivé d'OpenGL Shading Language pour définir ses propres filtres.

    Dans l'optique d'un portage de la version Windows, cette démarche est donc proscrite; à  ce propos, utiliser des structures et des pointeurs n'a rien de sale, mais il se peut que le logiciel d'origine n'ait pas été écrit dans l'optique d'être porté: il serait très dépendant du modèle d'organisation de la mémoire imposé par Windows et donc difficile à  convertir au Mac. Difficile de répondre sans étudier le code.
  • regattaregatta Membre
    06:12 modifié #12
    Mes notions de C et C++ sous windows ont quelques années  B) et je rame un peu (voir beaucoup) sur la syntaxe de type "struct BUFFER buffer[]" et son utilisation.

    Je n'ai pas trouvé d'exemple d'utilisation en Objective C !

    Pour l'instant, je décortique le code source (pas développé pour un portage) pour en comprendre l'organisation et voir comment porter cela en Objective C.

    Effectivement, j'ai laissé tombé l'utilisation de CoreImage, n'étant pas un spécialiste du traitement graphique et les méthodes standards ne répondent pas au besoin.

    Merci pour cette réponse qui me rassure quant à  l'utilisation de coreImage !
  • AliGatorAliGator Membre, Modérateur
    06:12 modifié #13
    dans 1313521393:
    Mes notions de C et C++ sous windows ont quelques années  B) et je rame un peu (voir beaucoup) sur la syntaxe de type "struct BUFFER buffer[]" et son utilisation.

    Je n'ai pas trouvé d'exemple d'utilisation en Objective C !
    Gné ?
    Faut revoir les bases même des notions de langage de programmation alors. Parce que l'Objective-C est une surcouche du C.

    Une struct, ou même une déclaration genre "struct BUFFER buffer[]", c'est pas "du C et C++ sous windows" ou "pas de l'Objective-C". C'est du C, point barre. Le C c'est du C, que ce soit sos Windows, Mac, Linux ou autre.
    Bon après il y a des variantes de C (C99, C Ansi...) mais les différentes entre ces variantes sont plutôt subtiles, en tout cas une syntaxe aussi basique que "struct BUFFER buffer[]" est commune à  toutes les variantes " c'est une base de la syntaxe du C en général depuis ses débuts " et surtout, ces variantes n'ont rien à  voir avec le fait que tu sois sur une plateforme Win/Linux/Max

    Après, l'Objective-C c'est une surcouche du C, donc tout ce que tu peux faire en C tu peux le faire en Objective C

    Donc quand tu parles de tes notions de C... sous Windows, dans ce contexte de comprendre la syntaxe du langage, ça n'a pas trop de sens. Quant au fait de trouver un exemple d'utilisation en Obj-C bah suffit de prendre un exemple en C puisque l'Objective-C en est une surcouche.

    dans 1313521393:
    Effectivement, j'ai laissé tombé l'utilisation de CoreImage, n'étant pas un spécialiste du traitement graphique et les méthodes standards ne répondent pas au besoin.

    Merci pour cette réponse qui me rassure quant à  l'utilisation de coreImage !
    Bah heu que tu utilises CoreImage ou pas (bien que l'utiliser permettrait d'optimiser les traitements), la question est surtout de savoir si tu as une lib fonctionnant sous OSX qui permet de faire la même chose que celle utilisée par ton soft sous Windows.
    Si tu en as une faut voir comment adapter l'API. Sinon, bah t'es dans la merde (vu qu'il te faudra la développer toi-même).

    Ensuite, commence par porter la partie métier avant de porter la partie vue. Car si tu as que la partie métier au moins tu pourras par exemple la piloter en mode console au pire, et puis la vue ne sera pas grand chose à  porter quand tu auras le métier de fonctionnel. Alors que si tu portes la vue mais qu'au final tu n'arrives pas à  porter la partie métier parce que tu ne trouves pas de lib équivalente, t'auras plus qu'à  tout jeter.
  • regattaregatta Membre
    06:12 modifié #14
    Ce que je voulais dire est tout simplement que j'ai  fait un peu de développement en C et C++ (sous windows) il y a 10 ans et rien de plus.

    Pour la librairie utilisée sous windows (fftw3), elle est disponible en open source et est déjà  recompilée ; donc pas de problème de ce coté !

    La partie vue ne me pose aucun soucis (une fenêtre d'affichage de la première image chargée et une fenêtre qui indique le traitement en cours) car j'utilise les classes Cocoa.

    Mon problème actuel est lié à  des erreurs de compilation sur du code pour accéder aux composants d'un des éléments du tableau de structure.

    La question est de savoir si mes restes de connaissance en language C (syntaxe avec & ou * avec des structures) sont en cause (sans doute) !

    Je suis preneur de tout exemple montrant la gestion des tableaux de structures (et en objective C si le compilateur est susceptible ou attend une syntaxe particulière  ;)).
  • AliGatorAliGator Membre, Modérateur
    06:12 modifié #15
    Imagine déjà  un tableau de int :[tt]int tableau[][/tt]. Pour accéder au 6e élément de ce tableau, tu fais juste :
    int unElementDuTableau = tableau[5];
    
    .

    Bah pour on tableau de struct, c'est pareil. Tu remplaces [tt]int[/tt] par [tt]struct BUFFER[/tt] et le code ne change pas : donc si tu as un [tt]struct BUFFER buffer[/tt] ça va donner :
    struct BUFFER unElementDuTableau = buffer[5];
    
    .
    Après tu manipiles ta [tt]struct BUFFER[/tt] comme n'importe quelle struct. Si par exemple elle est définie comme :
    struct BUFFER {<br />&nbsp; int width;<br />&nbsp; int height;<br />&nbsp; unsigned char* data;<br />};
    
    Bah pour accéder à  width tu fais comme n'importe quelle structure (et ça qu'elle vienne d'un tableau ou pas ça change rien :
    struct BUFFER unElementDuTableau = buffer[5];<br />int w = unElementDuTableau.width;
    


    Que ce soit des struct, des int, ou des double ou autre, les tableaux en C marchent toujours pareil, struct ou pas ça change pas le principe.
  • regattaregatta Membre
    06:12 modifié #16
    Voici un cas qui compile en C++ et pas en objective C

    La structure déclarée dans le .m
    <br />typedef struct dft1_Params<br />{<br />	int index,step;<br />	int w,h;<br />	union PIXEL *in;<br />	float *out;<br />	float *r,*g,*b;<br />} dft1_params[32];<br />
    


    La méthode utilisant la structure
    <br />//----------------------------------------------------------------------------------------------------<br />- (void)In3:(void*)vf inr:(void*)inr ing:(void*)ing inb:(void*)inb bandw:(BOOL)bandw<br />{<br />//	BeginThreads<br />//	SetThreads(w,h)<br />	int objects = 32;<br />	<br />	union PIXEL *f = (union PIXEL*)vf;<br />	float* infr = (float*)inr;<br />	float* infg = (float*)ing;<br />	float* infb = (float*)inb;<br />	<br />//	int k3 = 2*(h/2+1);<br />	<br />	minr = 0;<br />	ming = 0;<br />	minb = 0;<br />	<br />	if(bandw)<br />	{<br /><br />		NSOperationQueue *dft1Queue = [[[NSOperationQueue alloc] init] autorelease];<br />		NSBlockOperation *dft1BlockOperation = [[NSBlockOperation alloc] init];<br />		<br />		for(int obj=0; obj &lt; objects; obj++)<br />		{<br />			[dft1BlockOperation addExecutionBlock:^<br />			{<br />				struct dft1_params[obj].index	= obj;&nbsp; &nbsp; &nbsp; &nbsp; &lt;- erreur 1<br />				struct dft1_params[obj].step	= objects;&nbsp; &lt;- erreur 1<br />				struct dft1_params[obj].w		= w;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- erreur 1<br />				struct dft1_params[obj].h		= h;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- erreur 1<br />				struct dft1_params[obj].in		= f;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  &lt;- erreur 1<br />				struct dft1_params[obj].out		= infr;&nbsp; &nbsp; &nbsp;  &lt;- erreur 1<br />				[Dft dft1r:(void*)dft1_params[obj]];&nbsp; &nbsp; &nbsp;  &lt;- erreur 2<br />			}];<br />//			Démarre un Thread pour la méthode dft1r avec le paramètre dft1_params<br />//			StartThreads(dft1r,dft1_params)<br />		}<br />		<br />		[dft1Queue addOperation:dft1BlockOperation]; <br />//		EndThreads<br />	} <br />	else <br />	{<br />		NSOperationQueue *dft1Queue = [[[NSOperationQueue alloc] init] autorelease];<br />		NSBlockOperation *dft1BlockOperation = [[NSBlockOperation alloc] init];<br />		<br />		for(int obj=0; obj&lt;objects; obj++)<br />		{<br />			[dft1BlockOperation addExecutionBlock:^<br />			{<br />				struct dft1_params[obj].index	= obj;&nbsp; &nbsp; &nbsp;  &lt;- erreur 1<br />				struct dft1_params[obj].step	= objects;&nbsp; &lt;- erreur 1<br />				struct dft1_params[obj].w		= w;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- erreur 1<br />				struct dft1_params[obj].h		= h;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- erreur 1<br />				struct dft1_params[obj].in		= f;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  &lt;- erreur 1<br />				struct dft1_params[obj].r		= infr;&nbsp; &nbsp; &nbsp;  &lt;- erreur 1<br />				struct dft1_params[obj].g		= infg;&nbsp; &nbsp; &nbsp;  &lt;- erreur 1<br />				struct dft1_params[obj].b		= infb;&nbsp; &nbsp; &nbsp;  &lt;- erreur 1<br />				[Dft dft1r:dft1_params[obj]];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;- erreur 2<br />			}];<br />//			Démarre un Thread pour la méthode dft1rgb avec le paramètre dft1_params<br />//			StartThreads(dft1rgb,dft1_params)<br />		}<br />		<br />		[dft1Queue addOperation:dft1BlockOperation]; <br />//		EndThreads<br />	}<br />	<br />	valid_picture3 = TRUE;<br />	valid_picture1 = FALSE;<br />}<br /><br />
    


    Le code en commentaire est le code de gestion des threads en C++ remplacé par du code GCD

    L'erreur de compilation 1 est : Expected identifier '(' before '[' token
    L'erreur de compilation 2 est : Expected expression before 'dft1_params'

    Je suis avec xcode 3.2.6 (64 bits).

    Une idée pour me débloquer ?
  • SethySethy Membre
    06:12 modifié #17

    Je dois bien avoué que j'ai pas mal perdu en C classique.

    J'imagine que le symbole : ^ a pour rôle de créer la valeur attendue par la méthode addExecutionBlock (je me rappelle qu'on utilse cet opérateur pour inclure des sortes de pointeurs sur les fonctions).

    Si c'est le cas, n'est-il pas possible de le créer au préalable et d'ensuite l'appeler plus classiquement [dft1BlockOperation addExecutionBlock:data] ?

    Enfin, c'est ce que je ferais.

    Sethy
  • AliGatorAliGator Membre, Modérateur
    août 2011 modifié #18
    Sethy : le "^" est la syntaxe pour les blocks, une extension du C ajoutée par Apple (et très puissante puisque permet de faire des closures et des fonctions anonymes, ça manquait cruellement au langage où l'on était obligé de faire des pointeurs de fonctions avec un contexte void* avant ça). Rien de choquant là  dedans (par contre le fait que tu ne connaisses pas n'est pas choquant, c'est assez "nouveau" et n'est pas tout à  fait du "C classique" puisque c'est une extensions)


    Par contre @regatta : le code que tu nous as copié ne compile pas, même en C.
    Il compile peut-être en C++, mais l'Objective-C est une surcouche du C, pas du C++.
    La preuve j'ai copié/collé uniquement ceci dans un fichier que j'ai nommé "struct.c" et j'ai essayé de le compiler (donc en C pur, pas d'Objective-C là  dedans) et il me sort la même erreur :
    typedef struct dft1_Params<br />{<br />	int index,step;<br />	int w,h;<br />	union PIXEL *in;<br />	float *out;<br />	float *r,*g,*b;<br />} dft1_params[32];<br /><br />int main(int argc, char* argv&#91;])<br />{<br />	struct dft1_params[4].index	= 4; // &lt;-- même erreur que ton erreur 1 ici<br />}
    


    Y'a un truc que je trouve pas clean dans ta déclaration : un typedef normalement ça s'utilise pour déclarer un type.
    [tt]typedef declaration_complete_du_type nom_court_du_type[/tt]
    Exemple :
    typedef struct toto<br />{<br />&nbsp; int a;<br />&nbsp; int b;<br />} s_toto;
    
    Avec ça tu peux utiliser le type "s_toto" au lieu d'utiliser le type "struct toto", c'est plus court et lisible (et c'est le but de typedef, rendre le code plus lisible en donnant des noms plus explicites à  des types complexes)

    Or là  tu mets, à  la place du nom court, une déclaration qui ressemble à  une déclaration d'une variable de type tableau, avec [tt]dft1_params[32];[/tt]. Ca veut dire quoi ta déclaration ? Que du déclares un type qui s'appelle "dft1_params[32];" et équivaut à  une structure ? Mais un type ça n'a pas de "[]" !

    Si tu veux déclarer un type nommé dft1_params_type, puis une variable dft1_params_var qui représente un tableau de 32 objets de ce type, il faut écrire :
    typedef struct dft1_Params<br />{<br />	int index,step;<br />	int w,h;<br />	union PIXEL *in;<br />	float *out;<br />	float *r,*g,*b;<br />} dft1_params_type;<br />// Et pour déclarer ton tableau, utilises la même syntaxe que si tu écrivais &quot;int mavar[32]&quot; par exemple :<br />dft1_params_type dft1_params_var[32];
    
    Ou alors tu n'utilises pas le typedef et utilises directement le vrai nom du type :
    // Tu déclares le type :<br />struct dft1_Params<br />{<br />	int index,step;<br />	int w,h;<br />	union PIXEL *in;<br />	float *out;<br />	float *r,*g,*b;<br />}<br />// puis tu déclares une variable dece type :<br />struct dft1_Params dft1_params[32];
    
    Ou encore si tu n'as pas besoin de manipuler le type proprement dit plus tard, tu peux déclarer directement le type (ta struct) en même temps que tu définis la variable :
    // Déclaration d&#039;une variable de type struct, avec détail du type lors de la déclaration :<br />struct<br />{<br />	int index,step;<br />	int w,h;<br />	union PIXEL *in;<br />	float *out;<br />	float *r,*g,*b;<br />} dft1_params[32];
    
    Mais dans ton code tu fais un mix des deux et je t'avoue que même si c'est peut-être valable en C++ (et encore j'en suis pas sûr) ça me parait trop litigieux et pas clair de savoir ce qui est exactement déclaré pour être acceptable.
  • SethySethy Membre
    06:12 modifié #19
    Je peux peut-être apporter un élément (aussi de mémoire qui me trahit parfois). En C++, la notion de classe est en fait une extension de la notion de structure, au point qu'une structure n'est finalement qu'une classe simplifiée (une forme de compatibilité descendante si vous voulez). On pourrait presque dire qu'une structure est une classe ayant tous les membres publiques et toutes les méthodes publiques.

    Question syntaxe, c'est la syntaxe des structures C qui est simplement étendue aux classes C++.

    Donc, sans le savoir, regetta a peut être utilisé des avancées C++ liées aux structures, qui ont transformé sa structure en classe C++ et qui sont donc de facto inconnues en C.

    Sethy
  • SethySethy Membre
    06:12 modifié #20

    Sachant cela, vous identifierez tout de suite (pensez mot-clé class = mot-clé struct) ;

    déclaration :
    class A<br />{<br />&nbsp; &nbsp; int x, y;<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; void setA(int _x);<br />}
    


    défintiion :

    void A::setA(int _x)<br />{<br />&nbsp; &nbsp; x = _x;<br />}
    


  • regattaregatta Membre
    06:12 modifié #21
    En fait, le code pour la structure en C++ est celui là  :

    <br />struct dft1_Params<br />{<br />	int index,step;<br />	int w,h;<br />	PIXEL *in;<br />	float *out;<br />	float *r,*g,*b;<br />} dft1_params[32];<br />
    


    PIXEL étant une union.

    En objective C, la déclaration sous la forme

    <br />struct dft1_Params<br />{<br />	int index,step;<br />	int w,h;<br />	union PIXEL *in;<br />	float *out;<br />	float *r,*g,*b;<br />} dft1_params[32];<br />
    


    résout le problème  :D
    J'avais fait beaucoup de tests et donc laissé le typedef par erreur !

    Merci pour votre aide
  • CéroceCéroce Membre, Modérateur
    06:12 modifié #22
    Tu peux aussi retirer l'union, d'ailleurs, je suis étonné que tu n'aies pas de plainte du compilateur.
  • regattaregatta Membre
    06:12 modifié #23
    Justement non, j'ai une plainte si je ne l'ajoute pas  B)
  • CéroceCéroce Membre, Modérateur
    06:12 modifié #24
    Je ne comprends pas entre quels membres se fait l'union  B)
  • AliGatorAliGator Membre, Modérateur
    06:12 modifié #25
    C'est sans doute parce que le type "union PIXEL" est déclaré plus haut (et sans typedef), genre
    union PIXEL {<br />&nbsp; unsigned char byte;<br />&nbsp; unsigned short word;<br />&nbsp; unsigned long dword;<br />}
    
    Une connerie comme ça

    Ca m'a l'air vraiment pas objet et bien bas niveau (voire crade) ton code d'origine...
  • regattaregatta Membre
    06:12 modifié #26
    Non, effectivement au niveau objet, le code est loin d'être génial.
    Pas de commentaires et deux classes de base Windows (Document et View) et des boà®tes de dialogue.

    Mais pour ce qui est de la puissance du programme, c'est le meilleur dans le genre !

    Le code est libre mais difficile à  suivre pour un débutant en traitement d'images  :'(
Connectez-vous ou Inscrivez-vous pour répondre.