1

Bonjour à tous!

Je développe depuis quelques mois un logiciel de création de sprites on-calc (pas très utile me direz vous, mais en fait ce projet fait parti d'un autre projet d'une toute autre envergure oui ).
Ceux qui m'ont aidé au début du développement de ce programme se souviennent peut être que je planchais alors sur le système de sauvegarde. J'ai résolu le problème de l'époque (à savoir réussir à changer le format du fichier créé pour lui appliquer ma propre extension) depuis longtemps, mais un autre problème persiste:
Pour sauvegarder le sprite, composé de pixels noirs et blancs, je me suis juste contenté de créer un fichier texte dont j'ai changé l'extension et qui n'est composé que de caractères "0" et "1".
Ca marche très bien et c'est rapide, mais bon le problème est que ça prend bien évidement beaucoup de place (8 fois plus que si je réussissais à manipuler directement les bits plutot que les octets).

J'en arrive donc à ma question:
Comment faire pour envoyer au fichier créé par mon système de sauvegarde des bits et non des octets?

J'ai pensé à un autre système:
-Réunir les caractères "1" et "0" huit par huit.
-Créer ainsi une chaine binaire.
-La converture en base 255 et stocker le caractère correspondant dans mon fichier.

Voila, comment faire et quelle est la technique la plus envisageable selon vous?

Enfin, connaissez vous un système de compression d'images qui pourrait s'appliquer à mes sprites (le RLE est quasi-inutile sur des images de cette taille, et ne ferait qu'augmenter la taille de mon fichier)?

Merci beaucoup d'avance et à bientôt!

EDIT: Une faute d'orthographe m'avais échappé roll .
avatar
Ancien pseudo : worfang.

2

ben comme tu le dis : tu regroupes tes 0/1 par 8 pour avoir un nombre entre 0 et 255 => tu prends le charactère correspondant.

c'est le plus simple et si en plus tes images sont petites, le plus efficace
Ancien pseudo : lolo

3

si je comprends bien tu sauvegardes ton fichier en mode texte ? pour avoir quelque chose de 8 fois plus efficace, tu n'as qu'à le sauvegarder en binaire, et inscrire ton sprite octet par octet à l'intérieur (c'est un peu curieux d'avoir envisagé de le sauvegarder de la façon que tu utilises actuellement d'ailleurs ^^)

sinon pour la compression, si RLE ne te convient pas (sur des images avec de larges plages en noir et blanc, ça peut être très efficace, mais je ne sais pas à quoi elles ressemblent dans ton cas), tu peux envisager une compression Huffman, LZ77, ou LZW; je ne sais pas laquelle des trois donnerait les meilleurs résultats sur des images a priori, mais je suis à peu près sûr que les 3 ont déjà été codées sur Ti, et tu dois donc pouvoir trouver des sources sans trop de problème happy
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

4

Merci de vos réponses!

Pour ce qui est de sauvegarder en mode texte >
Oui c'est un peu bizarre mais c'est le premier projet dans lequel je crée un fichier externe à partir de mon programme principal. J'ai utilisé la solution qui me paraissait la plus facile à mettre en place, en me disant que j'y reréfléchirait ensuite, ce que je fais aujourd'hui. wink

Donc je vais convertir mes chaines de huit bits en caractères.
Quelqu'un connait-il la commande qui permet d'avoir un caractère à partir de son code (en décimal ou en binaire)?

Pour ce qui est de la compression, je vais tester les systèmes proposés smile .

Encore merci! smile
avatar
Ancien pseudo : worfang.

5

Daniel Vouaux (./4) :
Quelqu'un connait-il la commande qui permet d'avoir un caractère à partir de son code (en décimal ou en binaire)?

En C il n'y en a pas : le caractère et son code sont deux choses exactement identiques (le caractère 'a' a une valeur de 97 par exemple, et tu peux écrire "int i = 'a';" sans problème)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

6

sinon, si tu n'as que 2 niveaux (blanc et noir => 0 et 1), voici une possibilité de format :

exemple pour l'image suivante :

1000001
0100010
0011100
0010100
0011100
0100010
1000001

l'image est constitué de
1x1, 5x0, 1x1, 1x0, 1x1, 3x0, 1x1, 3x0, 3x1, 4x0, 1x1, 1x0, 1x1, 4x0, 3x1, 3x0, 1x1, 3x0, 1x1, 1x0, 1x1, 5x0, 1x1


il suffit alors d'enregistrer la longueur de chaque suite de 0 et de 1, Si l'image commence par un 0, mettre 0 comme premiere longueur, et les dimensions de l'image (ici 9x9)

=> 9|9|0|1|5|1|1|1|3|1|3|3|4|1|1|1|4|3|3|1|3|1|1|1|5|1|

je conseil d'enregistrer les dimensions sur 2 octets

si un nombre dépasse 255, le mettre sur 2 octets : 264| => 255|9|
si un nombre est égal à 255, mettre 255|0| pour qu'il n'y ai pas de confusion.

petit calcul de place :

mon image : 9x9 pixels

avec ton ancienne methode texte : 81 charactères plus 2 pour les dimensions => 83 octets
avec la methode binaire du poste ./2 => 11 charactères plus 2 pour les dimensions => 13 octets
avec ma methode => 26 octets avec mon exemple, mais suivant les images, tu peux aller de 3 octets à 83 octets en fonction de la complexité de ton image

voila


si c'est pas clair, ben.... désolé happy



Ancien pseudo : lolo

7

Spipu> Merci de ton explication mais, si je ne me trompe pas, l'algorithme que tu présentes n'est qu'une adaptation du RLE. J'avais déjà vu un système de fonctionnement très proche du tien sur Internet, et je pense l'utiliser plus tard dans mon projet quand je m'occuperai de la gestion d'images bien plus grandes (et présentant de plus grandes plages de pixels noirs et blancs). Mes sprites, qui en majeure partie représenteront des personnages, alterneront des pixels noirs et blancs très proches, ce qui rend le codage RLE inutile dans mon cas (on perdrait plus de mémoire en codant en RLE que dans le cas d'un codage bit par bit sans compression).

Zephyr> Ok mais le truc c'est qu'auparavant j'écrivais octet par octet dans mon fichier de sauvegarde, "autosave". J'utilisais, pour par exemple enregistrer un "1", la commande suivante:

fputc(1, autosave);

Il y a certainement une autre commande, similaire mais me permettant de faire la "traduction"..
avatar
Ancien pseudo : worfang.

8

Daniel Vouaux (./7) :
Zephyr> Ok mais le truc c'est qu'auparavant j'écrivais octet par octet dans mon fichier de sauvegarde, "autosave". J'utilisais, pour par exemple enregistrer un "1", la commande suivante:
fputc(1, autosave);

Tu peux montrer ton code de sauvegarde ? Parceque ton code est correct, et il faut effectivement enregistrer "octet par octet", je ne suis pas sûr qu'on parle du même problème, et à vrai dire je ne vois même pas ce que tu veux traduire là.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

9

Quand je parlais de traduction, en fait je voulais parler du fait de passer d'une chaine de 8 bits à un unique octet.

Voici ma fonction de sauvegarde automatique: void autosave(char ecran1[1024], char ecran2[1024]) {      long i=0;      char j1=0, j2=0;            FILE *autosave = NULL;   autosave = fopen("autosave", "wb");         if (autosave != NULL)   {     rewind(autosave);          for (i=0;i<1024;i++) //sauvegarde du 1er écran.     {          j1=ecran1[i];          if (j1==0) fputc(0, autosave);          if (j1==1) fputc(1, autosave);     }     for (i=0;i<1024;i++) //sauvegarde du 2nd écran.     {          j2=ecran2[i];          if (j2==0) fputc(0, autosave);          if (j2==1) fputc(1, autosave);     }     fputc(0, autosave); //Les lignes suivantes définissent le format du fichier sauvegardé     fputc('V', autosave);     fputc('S', autosave);     fputc('X', autosave);     fputc(0, autosave);     fputc(OTH_TAG, autosave);          fclose(autosave);   } }

Mes sprites étant en niveaux de gris, j'ai deux écrans à sauvegarder. C'est aussi la raison pour laquelle il y a deux boucles.

Merci de porter autant d'attention à mon problème smile .
avatar
Ancien pseudo : worfang.

10

Daniel Vouaux (./9) :
Quand je parlais de traduction, en fait je voulais parler du fait de passer d'une chaine de 8 bits à un unique octet.

Ok, je comprends définitivement rien. 8 bits = 1 octet, donc passer d'une chaine d'octets à un octet... de quoi tu parles ? grin

[edit] oh je crois que j'ai capté, j'avais mal interpreté ta phrase; ta "chaine de 8 bits", c'est une chaine de 8 octets qui ne peuvent avoir que 0 ou 1 comme valeurs ? si oui, alors effectivement tu peux convertir ça dans une chaine 8 fois moins longue, mais je ne comprends pas pourquoi tu utilises un tel format, cf. réponse ci-dessous :
Voici ma fonction de sauvegarde automatique:

Ouch... Pourquoi ton tableau "ecran1" ne contient que des 0 ou des 1 ? c'est ici qu'il y a un problème, c'est pas du tout économique comme façon de sauvegarder des sprites :/ (à moins que tu ne l'aies fait intentionnellement pour des raisons de vitesse d'exécution, mais j'en doute)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

11

Daniel Vouaux (./9) :
Quand je parlais de traduction, en fait je voulais parler du fait de passer d'une chaine de 8 bits à un unique octet.

Le plus simple c'est comme dit Zephyr de stocker tout dans des octets de 0 à 255 (donc un octet = 8 pixels), et quand tu veux regarder/modifier un pixel utiliser des opérations logiques (&, |, et <<)... j'ai la flemme de googler mais tu devrais trouver facilement plein de tutos là-dessus ^^

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

12

Zephyr>
En fait c'est ça le problème grin !
Je ne sais pas comment faire pour transformer ma chaine de 8 caractère '0' ou '1' (par exemple: "01100010") en un seul octet (dans mon exemple: 01100010=98, il me faut donc trouver le caractère correspondant à 98 et le stocker dans mon fichier de sauvegarde, ce que je ne sais pas faire).

En effet stocker chaque bit comme un octet est tout à fait absurde d'un point de vue "économie de mémoire", et c'est pour ça que je veux stocker mes bits en tant que bits smile .

J'espère avoir été clair hum .
avatar
Ancien pseudo : worfang.

13

Pollux>
Quand tu parles des opérations logiques "&, |, <<", c'est dans quelle partie de la programmation, histoire que je cherche (je ne sais pas comment les utiliser à part le "&" pour les adresses de variables)?
avatar
Ancien pseudo : worfang.

14

15

Daniel > si j'ai bien compris ton problème, voilà une solution possible (argument char *t : tableau de 8 caractères) :
unsigned char caracteres_vers_binaire(char *t)
{
    unsigned int i;
    unsigned char b;
    
    for (i = 8; i; i--)
    {
        b <<= 1;
        b |= (*t++) == '1';
    }
    
    return b;
}


void binaire_vers_caracteres(unsigned char b, char *t)
{
    unsigned int i;

    for (i = 8; i; i--)
    {
        *t++ = (b & 0x80) ? '1' : '0';
        b <<= 1;
    }
}


0', '1'}.
Exemple :caracteres_vers_binaire("01001101") renvoie 77 (en décimal).

char t[8];
binaire_vers_caracteres(77, t) remplit t[] avec {'0', '1', '0', '0', '1', '1', '


Quant à savoir pourquoi ça marche, je te laisse chercher un peu wink
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

16

Daniel Vouaux (./13) :
Pollux>
Quand tu parles des opérations logiques "&, |, <<", c'est dans quelle partie de la programmation, histoire que je cherche (je ne sais pas comment les utiliser à part le "&" pour les adresses de variables)?

cherche qqch comme "opérations logiques" ou "manipulation de bits" smile

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

17

juste une question pour mieux m'aider à comprendre ton problème : au moment de l'exécution de ton programme, l'image est aussi enregistrée sous cette forme (1 octet par pixel) ? si oui, alors tu devrais plutôt chercher à améliorer ce point smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

18

peut-être qu'il l'"enregistre" seulement dans l'écran ? (en passant par les routines du tios pour récupérer les pixels individuels)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

19

Martial> En effet je n'avais pas tout à fait vu le concept comme tu me l'as présenté, merci smile .

Zerosquare> Merci, je vais essayer de comprendre comment ça marche, mais mon problème persiste: Comment faire pour stocker un nombre dans un octet? Est-ce que je peux faire, pour stocker le nombre 147 (par exemple), "fputc(147, autosave);"?

Pollux> Merci, je vais googler pour en apprendre un peu plus wink !

Zephyr> Ben c'est ça justement le problème, c'est que je stockais un pixel (donc un "1") par octet, et c'est ça que je voulais améliorer (donc en stockant 1 pixel par bit, donc stocker 8 pixels par octets).

Pollux (2ème intervention)> Je ne comprend pas trop ce que tu veux dire tsss . Pour enregistrer mon image, je crée un fichier externe.

Donc mon problème est maintenant dans la technique me permettant de stocker un nombre entre 0 et 255 dans un octet. Est-ce que "fputc(147, autosave);" ferait l'affaire?
avatar
Ancien pseudo : worfang.

20

oui
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

21

Merci beaucoup, je vais tester ça!
Encore merci à tous wink !
avatar
Ancien pseudo : worfang.

22

Ouf!

Après une aprèm de programmation, de mise au point, de correction de bugs et de relecture de vos conseils et de vos sources, j'ai enfin réussi!
Maintenant je peux enfin m'attaquer à la compression à proprement parler... Je vous tiens au courant!

Encore merci à tous, et à bientôt pour la suite!
avatar
Ancien pseudo : worfang.