Sérialisation de bits dans un unsigned char, pour du tga 1bpp

Résolu/Fermé
JwTdd Messages postés 21 Date d'inscription vendredi 25 janvier 2013 Statut Membre Dernière intervention 7 mai 2015 - Modifié par JwTdd le 12/11/2013 à 16:34
JwTdd Messages postés 21 Date d'inscription vendredi 25 janvier 2013 Statut Membre Dernière intervention 7 mai 2015 - 12 nov. 2013 à 17:56
Bonjour,

Afin d'économiser de l'espace j'essai en vain de créer des images tga noir et blanc en 1 bit par pixel en vain.

Pour du RGB je n'avais pas de problèmes, chaque couleurs prennent un octet que je peut mettre à la suite avec objet_ofstream.put.
Cependant pour du 1 bit par pixel je dois d'abord mettre chaque bit dans des paquet de 8bits avant de pouvoir l'écrire et jusqu'à maintenant je n'avais jamais eu besoin d'effectuer des opération en bitwise donc je bloque un peu.

Je suppose (peut être mal) qu'il faut que je fasse ceci:
tampon=0;

position=0;
...
/* A= 1 << 7 -> A=1000 0000
B= 1 << 6 -> B=0100 0000
C= A|1 << 6 -> C=1100 0000*/
tampon=(tampon << 1)|pixel;
position++;
if(position==7)
{
ecriretampon();
tampon=0; //reinitialiser tampon
position=0;
}


voila le code complet de mon programme de test:

main.cpp:

#include <iostream>

#include "image.hpp"
using namespace std;
int main()
{
short width=1000;
short height=1000;
octetbuf *oct = new octetbuf(width, height);
oct->createheader("bw.tga");
for(int i=0;i<(width*height);i++)
{
oct->addpixel(1); //remplir l'image de 1 (index du blanc)
}

oct->closefile();
return 0;

}

image.hpp:
#include <vector>

#include <string>
#include <fstream>
#include <iostream>
#include <stdint.h>
using namespace std;
class octetbuf
{
public:
octetbuf(short width, short height);
void createheader(string filename);
void addpixel(bool pixel);
void closefile();
private:
short m_width;
short m_height;
bool pixel;
uint8_t position;
unsigned char tampon;
string filename;
ofstream o;
//(filename.c_str(), ios::out | ios::binary)
};

image.cpp:
#include "image.hpp"

octetbuf::octetbuf(short width, short height)
{
m_width = width;
m_height = height;
}
void octetbuf::createheader(string filename)
{
position=0;
tampon=0x00U;
o.open(filename.c_str(), ios::out | ios::binary);
//Write the header
o.put(0);
o.put(0);
o.put(3); /* B&W */
o.put(0); o.put(0);
o.put(0); o.put(0);
o.put(0);
o.put(0); o.put(0); /* X origin */
o.put(0); o.put(0); /* y origin */
o.put((m_width & 0x00FF));
o.put((m_width & 0xFF00) / 256);
o.put((m_height & 0x00FF));
o.put((m_height & 0xFF00) / 256);
o.put(1); /* 1bpp */
o.put(0);
}
void octetbuf::addpixel(bool pixel)
{
/* A= 1 << 7 -> A=1000 0000
B= 1 << 6 -> B=0100 0000
C= A|1 << 6 -> C=1100 0000*/
tampon=(tampon << 1)|pixel;
position++;
if(position==7)
{
o.write (reinterpret_cast<char*>(&tampon), 1);
tampon=0x00U;
position=0;
}
}
void octetbuf::closefile()
{
if(position==7)
{
o.write (reinterpret_cast<char*>(&tampon), 1);
tampon=0x00U;
position=0;
}
else if (position!=0)
{
tampon= tampon << (7-position);
o.write (reinterpret_cast<char*>(&tampon), 1);
tampon=0x00U;
position=0;
}
o.close();
}

------------

Ce programme est censé me faire une image blanche de 1000 par 1000, sauf que j'obtiens un pixel noir tout les 8 bits, est ce que ça viens de mon opération sur les bit?
Je pensais que ça venais de put qui ne pouvais mettre que des signed char, c'est pour ça que j'ais mit à la place o.write (reinterpret_cast<char*>(&tampon), 1); mais toujours le même problème. Pourtant mon compteur de position semble juste de 0 à 7 il y a 8 valeurs :/


merci à l'avance pour toute aide ou indice.


EDIT: je viens de voir avec un éditeur hexadécimal que c'est bit tout a guauche chaque octet qui est a 0 au lieu de la valeur voulue (7F au lieu de FF).
A voir également:

1 réponse

Utilisateur anonyme
12 nov. 2013 à 17:12
Bonjour

de 0 à 7 il y a 8 valeurs
Oui et alors ? Tu incrémentes ton compteur AVANT de le tester. Donc quand tu testes position==7, position était à 6 pendant le traitement.
Fais l'incrémentation après, ou compare avec 8.
0
JwTdd Messages postés 21 Date d'inscription vendredi 25 janvier 2013 Statut Membre Dernière intervention 7 mai 2015 2
12 nov. 2013 à 17:56
Effectivement avec 8 ça marche beaucoup mieux, je cherche beaucoup trop loin en m'éloignant des bases surtout au niveau binaire (d'habitude se sont les librairies qui s'en occupent mais impossible de trouver pour du simple noir et blanc), d'ailleurs je viens a peine de m'apercevoir d'une erreur dans mon commentaires de code sur les bitwise alors que je suis censé me baser sur ça...
En tout cas merci ça fait deux jours que j'ais cherché partout sauf là.
0