Annonces Google
Serveur IRC
Serveur : irc.portlane.se
Canal : #AmigaNG
Activité du Site

Pages vues depuis 25/07/2007 : 25 168 254

  • Nb. de membres 187
  • Nb. d'articles 1 270
  • Nb. de forums 19
  • Nb. de sujets 20
  • Nb. de critiques 24

Top 10  Statistiques

Index du forum »»  Création-Développement »» Ecriture - lecture fichier sur plateformes différentes

Ecriture - lecture fichier sur plateformes différentes#1992

5Contributeur(s)
Pierro787thelliercortoElwoodYesCop
3 Modérateur(s)
K-LElwoodcorto
Pierro787 Pierro787icon_post
Bonjour à tous,

Je suis actuellement en train de travailler sur le développement d'une application Amiga OS4.1 et MorphOS en C qui permettrait de créer et lire via la bibliothèque SDL des fichiers binaires contenant des images fixes, des spritesheets ainsi que des fichiers d'impression 3D, le tout compressé. Le but serait de pouvoir visualiser simplement sur n'importe quelle plateforme du contenu 3D pré-rendu réalisé à partir du fichier 3D contenu dans le fichier "conteneur".

Même sur un PC puissant, réaliser un turntable d'un objet à imprimer en 3D peut prendre plusieurs heures pour peu que l'on souhaite une qualité photographique. En rendant l'animation en spritesheet, on peut obtenir cette qualité avec une puissance bien moindre et un rendu immédiat sans prendre trop de place...

On peut ainsi contenir des bijoux virtuels à imprimer, relativement simplement, même sur des machines pour l'instant peut concernées par l'impression 3D comme les Amiga NG.

Par contre, je me heurte aux problèmes de lecture fwrite / fread qui écrivent et traitent les fichiers différemment selon la nature du processeur ( octets inversés sur x86 et dans le bon ordre sur powerpc par exemple). Du coup, il faut créer les fichiers "conteneurs" sur chaque plateforme pour être certain que le lecteur associé saura bien les traiter.

Y a-t-il un autre moyen de traiter ce problème, de manière plus universelle ?

Par avance, merci

Pierre
thellier thelliericon_post


Pour être clair il y a deux sens d' "ordering" à la motorola ou à l'intel
Donc si tu lis ou écris une fichier d'un format donné il faut suivre la spec du format pour son ordering (Idem si tu créée un format = faut se décider)


Par exemple pour IFF c'est motorola
 FB->FileByteOrder='M';


Après on peut auto détecter l'ordering de ta machine
WORD One=1;
UBYTE *TestOrder=(UBYTE *)&One;


 if(TestOrder[1]==1)
  {FB->ComputerByteOrder='M';}
 else
  {FB->ComputerByteOrder='I';}


Et on réordonne si besoin


FB->Reorder=(FB->ComputerByteOrder!=FB->FileByteOrder)



/*==========================================================================*/
UBYTE GetByte(FileBuffer3D *FB)
{
UBYTE val;


 val=FB->pt[0];
 GetSkip(FB,1);
 return(val);
}
/*==========================================================================*/
UWORD GetWord(FileBuffer3D *FB)
{
UBYTE vals[2];
UWORD *pt=(UWORD*)vals;


 if(!FB->Reorder)
 {
 vals[0]=FB->pt[0];
 vals[1]=FB->pt[1];
 }
 else
 {
 vals[0]=FB->pt[1];
 vals[1]=FB->pt[0];
 }
 GetSkip(FB,2);
 return(*pt);
}
/*==========================================================================*/
ULONG GetLong(FileBuffer3D *FB)
{
UBYTE vals[4];
ULONG *pt=(ULONG*)vals;


 if(!FB->Reorder)
 {
 vals[0]=FB->pt[0];
 vals[1]=FB->pt[1];
 vals[2]=FB->pt[2];
 vals[3]=FB->pt[3];
 }
 else
 {
 vals[0]=FB->pt[3];
 vals[1]=FB->pt[2];
 vals[2]=FB->pt[1];
 vals[3]=FB->pt[0];
 }
 GetSkip(FB,4);
 return(*pt);
}
/*==========================================================================*/
float GetFloat(FileBuffer3D *FB)
{
UBYTE vals[4];
float *pt=(float*)vals;


 if(!FB->Reorder)
 {
 vals[0]=FB->pt[0];
 vals[1]=FB->pt[1];
 vals[2]=FB->pt[2];
 vals[3]=FB->pt[3];
 }
 else
 {
 vals[0]=FB->pt[3];
 vals[1]=FB->pt[2];
 vals[2]=FB->pt[1];
 vals[3]=FB->pt[0];
 }
 GetSkip(FB,4);
 return(*pt);
}
/*==========================================================================*/
void GetSkip(FileBuffer3D *FB,LONG n)
{
 FB->pos= FB->pos + n;
 FB->pt = FB->pt  + n;
}
/*==========================================================================*/

corto cortoicon_post
Pierro787 : Tu peux charger en mémoire des blocs de données avec fread() par exemple, et ensuite parcourir ce bloc pour convertir par exemple les mots 32 bits, pour les mettre dans les variables ou structures où ils seront utilisés.
Ou alors tu te fais une fonction fread32 qui lit un mot de 32 bits et avec un #ifdef convertit le mot dans le cas où c'est nécessaire.

Elwood Elwoodicon_post
@Corto

N'y a-t-il aucune fonction pour faire la conversion ? ça semble dingue.
--
Philippe Ferrucci
Avec une Sam460 et AmigaOS 4.1, je suis eco-responsable. Cool !
Pierro787 Pierro787icon_post
Merci à tous pour vos réponses !

Je vais regarder en détail le code fourni dans ce fil. A priori, il y a un autre problème, je travaille essentiellement avec des structures C (classiques pour traiter des fichiers binaires en C) et selon les plateformes, certains compilateurs / processeurs ajoutent des octets de synchronisation entre chaque membre de la structure lors de l'écriture dans le fichier binaire. (Vu dans un forum US sur la programmation en C)

Du coup, là encore, selon la plateforme, le fichier peut devenir illisible avec le même player. Je vois que sur x86, des octets "00" sont ajoutés entre les membres de ma structure (et pas sur powerpc).

En fait, j'ai toujours entendu dire que le C était ultra portable mais ce n'est vrai que tant qu'on reste dans une même famille de processeurs...

Autre point, je voulais porter mon encodeur / player sur Amiga classic m68k mais je crois qu'on est limité à 16 Mo de RAM maxi ? Du coup, ça fait un peu juste pour décompresser certaines données avec zlib.

Pierre


Vive l'Amiga !
YesCop YesCopicon_post
Si il y a des octets ajoutés, c'est sûrement à cause du fait que certains systèmes aiment avoir leur structure alignées sur 32 bits.
Un exemple simple.
Une structure de trois octets sera peut-être remplacée par un mot long de 32 bits.
La joie du padding!

Pour éviter cela, je ne vois qu'un moyen.
C'est d'enregistrer tes infos octet par octet et tu ma?triseras ainsi la taille.
 
Pierro787 Pierro787icon_post
YesCop, je pense que c'est bien ça le problème. Ma structure contient des mélanges de char, de int, de unsigned char, bref, des membres de longueur différentes...

Je crois que j'ai fait l'erreur de développer d'abord sous Windows 7 avec CodeBlocks pour concevoir mon code et le porter ensuite sur AmigaOne 500 sous AmigaOS4.1. J'aurais du faire l'inverse car le traitement des données semblent bcp plus clean et conforme sur powerpc.

Juste un point, sur ARM, l'ordre des octets est-il similaires à Intel ou Motorola ?

Merci,

Pierre
Vive l'Amiga !
Elwood Elwoodicon_post
Plus d'infos sur l'alignement : http://fr.wikipedia.org/wiki/Alignement_en_m%C3%A9moire
--
Philippe Ferrucci
Avec une Sam460 et AmigaOS 4.1, je suis eco-responsable. Cool !
thellier thelliericon_post

Exactement comme le dis Corto tu dois lire ton fichier donnée par donnée et non pas une struct entiére sinon tu risque des problèmes


cad que si ta struct est ainsi dans ton fichier


struct toto{
ULONG x;
WORD n;
UBYTE flag;
};
struct toto T;


Il faut faire


T.x    =GetLong(FB);
T.n    =GetWord(FB);
T.flag =GetByte(FB);


Au préalable j'ai chargé tout le fichier en mémoire dans un buffer et FB est ma structure qui me dit ou j'en suis de sa lecture


>Juste un point, sur ARM, l'ordre des octets est-il similaires à Intel ou Motorola ?
Qu'importe utilise le code ci dessus qui detecte mon ComputerByteOrder et ça marche à tout les coups


Alain


PS:
sur l'alignement des struct il existe des directives pour s'en passer comme
#pragma pack(2)
voir la doc des compilo


On peut aussi rajouter du "padding" aux structs perso pour les aligner de force à 32 bits
struct toto{
ULONG x;
WORD n,pad;
UBYTE flag,pad1,pad2,pad3;
};


Mais de toute façon lire des struct entiére dans le fichier est une mauvaise idée car il faudra réordonner les valeurs quand même donc les relire/écrire

corto cortoicon_post
Merci à Alain d'avoir illustré avec du code.

Et je confirme le "pragma pack". Dans une structure, je conseille déjà d'éviter de mettre un char, un int, un char, un int, ... Dans ce cas, ça pourrait utiliser 4 mots de 32 bits. Mais attention, il me semble que le C ne garantit pas que les champs d'une structure seront dans le même ordre que celui défini, même si je ne sais pas si on rencontre ce cas.

La portabilité du C a des limites :-) Le langage a la particularité d'autoriser une certaine liberté d'implémentation.

Petites Annonces

0 annonce(s) publiée(s)

Consulter

AmigaOS 4.1

Laissez-vous tenter par
AmigaOS 4.1
AmiTheme

AmiTheme