Salut à tlm,
Je suppose que j´aurais pu poster ça dans le topic de JYY² sur C++ mais, bhah, y´a pas que du C++ dans mes questions du jours alors...
Je vais simplement faire une liste de questions sans ordre précis. Évidemment, libre à vous de répondre à une ou plusieurs d´entre-elles.
Question de ´mise en contexte´, j´ai commencé à travailler sur le schéma d´un . tga avec le fichier de spec qui, il me semble, est celui officiel pour la version 2.0:
http://www.opennet.ru/docs/formats/targa.pdf
J´ai voulu essayé de m´y mettre sans aucun tutorial ( bien que je sois au courant de la présence d´un tuto sur le sujet sur NeHe et que j´ai l´intention de m´en servir si un besoin surgit) afin de pratiquer tout ce qui attrait au chargement d´un fichier plus compliqué qu´un . txt
. Ainsi, c´est en lisant le . pdf que plusieurs questions ont surgit dans ma tête.
1) Un bit, corrigez moi si j´ai mal pigé, est l´unité de mesure la plus ´basse´. Il s´agit de 0 et de 1. Lorsque l´on a 8 bits, l´on obtient un byte. Hors, en français, byte est ´octet´ ( octet - octal - octogone - 8 côtés...
) . Quel est le terme pour bit ?
2) Sur un PC commun, une lettre prend bite 1 byte, d´où le sizeof d´un char ?
3) Si une image est storée en 32 bpp, il y a bien 32 bits pour chaque pixel et, conséquemment, 4 bytes pour chaque pixel ?
- ça devient moins idiot à partir d´ici -
4) La notation utilisée par le C++ pour représenter des bytes de donnée ressemble vaguement à de l´hexadécimal ( vous savez, un truc du genre 0x1234). Hors, je ne connais pas cette notation. Est-ce vraiment de l´hexa ?
5) Comment fonctionne cette notation ? Je sais qu´il y a un système de classement du genre ´le byte le mois significatif en premier et le plus significatif en dernier´ qui doit être inversé pour, je pense, une machine macintosh ( et qu´il s´agit d´un truc appellé ´endian´ bien qu´on entre ici dans quelque chose de vague pour moi).
6) Dans l´éventualité où l´explication de la notation est plutôt, disons, longue, pouvez-vous simplement m´en donner le nom, que je fasse une recherche par moi-même avec les bons mots clefs ( ou alors me fournir un site ou une référence quelqconque) ?
7) Dans l´éventualité où une explication pour la notation est fournie, comment on traite les différentes valeurs ( plus à moins significative) dans C++ ?
Merci beaucoup pour vos réponses !
Les 3 premier sont vrai, le mots est le même en francais et en anglais pour bit.
4) oui, 0x introduit une notation héxa
5)Tu te fiche de ce problème, il est géré par le processeur. Toi tu écrit juste ne mettant dans l´ordre logique, c´est a dire le chiffres qui a le plus de signification en premier ( comme en base 10).
6)les notation sont big et ittle endian, mais tu n´a pas a t´en préoccupé a moins que tu fasse de l´assembleur.
7)Pas besoin de réponse, mais tu peut utiliser < < et > > plus les opérateur booléan ( and, or etc... ( oui, oui, je sais, en C il y a une notation plus propre) et il y a une fonction quelques part qui fait tourner pour manipuler les nombres à leur niveau binaire, mais c´est très rarement utile.
P.S. Pour la question 3 : effectivement du bitmap 32 bits prend 4 octets ( plutot que byte) par pixel. Mais comment divise tu 32 par 3 ( le nombre de couleur primaire) ? impossible, donc il n´y a que 3 octets qui servent pour les couleurs ( comme dans du bitmap 24 bits) et le dernier est le gamma ( ou alpha ? ), c´est a dire la transparence du pixel.
Comme le disait à très juste titre, Dnob, RGBA
Red Green Blue et Alpha Channel ^^
Merci bien !
Pour avoir commencé un programme brouillon visant à lire étape par étape le contenu d´un . tga ( en tâchant d´exclure le moins de champ possible), je vois surgir des questions hors d´un mystérieux coin sombre.
Dans un . tga, le champ 5.6, tel que mentionné dans:
http://www.opennet.ru/docs/formats/targa.pdf
est un champ de 1 byte, soit 8 bits, dont je dois récupérer chacun des bits puisqu´ils ( ou elles ? c´est féminin ou masculin
? ) ont tous une signification différente.
J´ai cherché une façon de faire, un type de buffer à utiliser dans fread. Mes premières idées étaient n´importe quoi jusqu´à ce que je pense à faire un champ de bits tel qu´expliqué dans le cours de m. Casteyde:
http://casteyde.christian.free.fr/
J´ai donc fait une structure contenant 8 variables différentes pour les 8 bits:
struct TGADescriptor
{
int bits0 : 1;
int bits1 : 1;
int bits2 : 1;
int bits3 : 1;
int bits4 : 1;
int bits5 : 1;
int bits6 : 1;
int bits7 : 1;
};
J´ai ensuite créer un objet avec cette structure:
struct TGADescriptor ImageSpecDesc;
Et j´ai maudit cet objet en tant que buffer:
fread(&, sizeof(TGAbyte), 1, tga);
Première constatation/question: ça fonctionne mais le bit #5 est négatif ? ! Il devrait normalement être égal à 1, pourquoi est-il négatif ? Comment on bit peut être négatif de toute façon ?
Seconde constatation/question: ça ne me semble pas très efficace, y aurait-il une meilleure façon de faire ? Il semble qu´il soit impossible de faire un tableau [] de bits, ce qui m´aurait permis de facilement faire un objet qui s´adapte avec de l´allocation dynamique... ![]()
1 bit vazut soit 0 soit -1 forcement.
Car c´est toujours le bit le plus significatif qui s´il vaut 1 alors le chiffre est négatif ( c´est pour ça que la vrai valeur de true c´est pas 1 mais -1).
MAis tu peut récupérer ton octet dans un char puis tester chacun de ses bits un par un plutot que de récupérer 8 bits.
exemple, si tu as récupérer dans char Octet;
bool Bit[8]
for ( int I=0;I<8;Bit[I++]=Octet && 1,Octet>>1);
/ /ce devrait marcher.
Si ca peut t´aider, j´ai ecrit une fonction d´ecriture et de lecture d´un TGA, TRES MINIMALISTE ( c´est ce que je voulais).
---
/ /
--------------------------------------------------
------------------------
/ / Nom : sauveTGA
/ / Sauve une image au format TGA ( raw avec un header de 18 octets)
/ /
--------------------------------------------------
------------------------
void sauveTGA(stImage &, char* name)
{
FILE* fichier;
unsigned char mychar;
unsigned short myshort;
fichier=fopen(name, " wb");
if ( fichier!=NULL)
{
// Ecris entete TGA
mychar=0; / / size of ID field that follows 18 byte header ( 0 usually)
fwrite(&, 1, 1, fichier);
mychar=0; / / type of colour map 0=none, 1=has palette
fwrite(&, 1, 1, fichier);
mychar=2; / / type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
fwrite(&, 1, 1, fichier);
myshort=0; / / first colour map entry in palette
fwrite(&, 2, 1, fichier);
myshort=0; / / number of colours in palette
fwrite(&, 2, 1, fichier);
mychar=0; / / number of bits per palette entry 15,16,24,32
fwrite(&, 1, 1, fichier);
myshort=0; / / image x origin
fwrite(&, 2, 1, fichier);
myshort=0; / / image y origin
fwrite(&, 2, 1, fichier);
myshort=image.m_Taillex; / / image width in pixels
fwrite(&, 2, 1, fichier);
myshort=image.m_Tailley; / / image height in pixels
fwrite(&, 2, 1, fichier);
mychar=32; / / image bits per pixel 8,16,24,32
fwrite(&, 1, 1, fichier);
mychar=0x00; / / image descriptor bits ( vh flip bits) ( 00vhaaaa)
fwrite(&, 1, 1, fichier);
// Ecrit pixels
fwrite(image.m_paPixels, 4, image.m_Taillex * image.m_Tailley, fichier);
fclose(fichier);
}
else
{
printf("Erreur ouverture fichier %s\n", name);
}
}
/ /
--------------------------------------------------
------------------------
/ / Nom : loadTGA
/ / Sauve une image au format TGA ( raw avec un header de 18 octets)
/ /
--------------------------------------------------
------------------------
void loadTGA(stImage &, char* name)
{
FILE* fichier;
unsigned char mychar;
unsigned short myshort;
fichier=fopen(name, " rb");
if ( fichier!=NULL)
{
// Ecris entete TGA
mychar=0; / / size of ID field that follows 18 byte header ( 0 usually)
fread(&, 1, 1, fichier);
mychar=0; / / type of colour map 0=none, 1=has palette
fread(&, 1, 1, fichier);
mychar=2; / / type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
fread(&, 1, 1, fichier);
myshort=0; / / first colour map entry in palette
fread(&, 2, 1, fichier);
myshort=0; / / number of colours in palette
fread(&, 2, 1, fichier);
mychar=0; / / number of bits per palette entry 15,16,24,32
fread(&, 1, 1, fichier);
myshort=0; / / image x origin
fread(&, 2, 1, fichier);
myshort=0; / / image y origin
fread(&, 2, 1, fichier);
myshort=0; / / image width in pixels
fread(&.m_Taillex, 2, 1, fichier);
myshort=0; / / image height in pixels
fread(&.m_Tailley, 2, 1, fichier);
mychar=32; / / image bits per pixel 8,16,24,32
fread(&, 1, 1, fichier);
mychar=0x00; / / image descriptor bits ( vh flip bits) ( 00vhaaaa)
fread(&, 1, 1, fichier);
/ / Cree l´image
init_image(image, image.m_Taillex, image.m_Tailley);
/ / Lit les pixels
fread(image.m_paPixels, 4, image.m_Taillex*image.m_Tailley, fichier);
fclose(fichier);
}
else
{
printf("Erreur ouverture fichier %s\n", name);
}
}
pour les TGA, je ne connais pas bien le format, mais en tout cas, si tu cherches des fonctions, tu as déja celle de Lapintade, mais tu as aussi celles de SDL_image, sur le site de la SDL, qui doivent etre open source, sinon, sur le site du dieu Nehe, tu as des tutos avec des textures, et si tu télécharges les versions GLUT, tu as avec des fonctions pour lire les TGA
En ce qui concerne Big Endian et Little Endian, en effet, tu n´as souvent pas a t´en servir.
INTEL marche en Little Endian
Motorola marche en Big Endian
Tous les protocoles Internet sont codés en Big Endian
Donc tu auras a y faire attention uniquement si :
- tu fais du réseau bas niveau ( winsock) avec htons()
- tu parses des fichiers binaires et que tu lis des nombres octet par octet ( car si tu lis correctement, fread gere ça tout seul)
- tu lis octet par octet des short, int, etc...
Une petite fonction pour ton pross :
unsigned char EndianTest[2]={1,0};
short x;
x=*(short*)EndianTest;
if ( x==256)
/ / Big endian
else
/ / Little endian
sinon, l´hexadécimal est une base 16 :
les chiffres :
0123456789ABCDEF
et F + 1 = 10
un chiffre hexa est un paquet de 4 bits ![]()
On code donc un octet sous 8 bits = 2 chiffres hexa, c´est comme ça que les éditeurs de secteur te présneteront les données.
Sinon, chaque caractere est codé sous 1 octet, par un codage universel ( genre ´A´ = code 65)
ce codage s´appelle ASCII
Merci à tlm pour vos réponses, je fonce à nouveau dans une question.
J´ai lu le premier pixel dans un field Image Data en 32bpp ( donc j´ai lu les 4 premiers bytes). Le résultat a été que le bleu était dans le premier byte, le vert dans le deuxième, le rouge dans le troisième et le alpha dans le quatrième. C´est normal ? Je vivais avec l´impression que l´ordre était ARGB comme mentionné dans le document de référence ( "Attribute, Red, Green and Blue ordered data for True-Color").
ça dépend des codages ![]()
des fois c´est :
RGBA, BGRA, . .. mais souvent le A en dernier ![]()
Merci bien... j´ai un peu de mal à suivre l´ordre logique des choses.
Ça dépend du codage, ce qui signifierait logiquement qu´un format signifie un ordre pour chaque byte du code de couleurs ( à tout le moins, logiquement, sans quoi, comment sait-on quel nombre est quelle couleur ? ).
Par conséquent, le . tga serait un BGRA et le document de référence serait dans le faux ?
Oh et pendant que je suis dans un bombardement de questions
, j´aimerais savoir, pour un bpp de 32, 32 / 4 = 8 = 1 byte ce qui fait 4 bytes par pixel soit R:G:B:A ( ou B:G:R:A ici). Pour le 24 bpp, 24 / 3 = 8 = 1 byte ce qui fait 3 bytes par pixel soit R:G:B ( ou probablement B:G:R ici). Mais pour un bpp de 16 ? Ou bien il n´y a que deux channels de couleur ou alors chaque channel ne dispose pas d´un byte en entier... auquel cas, comment savoir ou commence et ou termine le channel ? Un 16 ne se divise pas en 3 et je vois mal un format qui vient avec moins de bits par pixel avoir un channel alpha ( division par 4) alors que celui de 24 n´en n´aurait pas ?
Tu as raison, et c´est un vrai problème. En même temps je n´ai jamais vu de qualité à 16 bits ailleurs que dans les paramètre d´écran de windows.
Mais pas dans des logiciels de création d´images. Donc je ne sais pas si c´est très utilisé pour l´enregistrement ou si c´est juste un truc de windows.
Bon je n´étale pas ici ma science puisque je suis l´ignorant mais photoshop fait très bien des . tga en 16 bits...
Je suppose qu´à la limite je peux me passer du format 16 bits pour un jeu ( j´ignore si un windows en 16 bits peut faire l´affichage d´une image storée en 32 bits ou s´il est facile de faire le passage d´une texture 32 bits vers un buffer de 16 mais, dans tous les cas, quelle genre de machine est barrée au 16 bits de toute manière ? Pas très pragmatique comme vision des choses par contre)...
Je bump ma question comme elle commence à se diriger vers la troisième page.
Quelqu´un connait l´organisation des bits dans un pixel de 16 bits ( image en 16 bpp) ?
Je ne rebumperai pas le topic une seconde fois ( par respect, évidemment) et je doute que je vais avoir d´autres questions après celle-ci, les gros problèmes étant déjà solutionnés ( grâce à vous ! ).
Merci de vos réponses
Je connais le codage sous 16 bits :
en fait tu as :
- 5 bits pour le rouge ( 32 possibilités)
- 6 bits pour le vert ( 64 possibilités)
- 5 bits pour le bleu ( 32 possibilités)
ça te fait 16 bits
et j´attends ta question : " pkoi 6 pour le vert ? "
--> Parce que l´oeil humain réagit mieux aux nuances de vert qu´au rouge et qu´au bleu ! Et oui ! ! y´a eu des études de faites ![]()
Au début, ils voulaient faire 5,5,5 mais ça faisait chier de perdre un bit, donc voila !
les couleurs sous 16 bits, c´était donc chiant a " décortiquer" car ce n´est pas aligné aux octet, heureusement, ça a été une des premieres optimisations des cartes graphiques, convertir electroniquement des " 5 bits" en 1 octet.
PS : please, ne dit plus " byte" j´ai horreur de ce mot, dis " octet"
)
byte byte byte byte byte
Mes excuses ![]()
les images 16 bits se perdent bien entendu...
Tout comme les images 8 bits ( couleurs indexées, comme les Gif, et les PNG 8 bits utilisés dans RPG Maker ( pouhahah ! !) etc ! ) ça se paume également car pour faire des dégradés avec ça : ouch ! !
Avant quand y´avait peu de couleurs, y´avait la technique du dithering :
regarde cette image ( fort charmante)
http://www.visgraf.impa.br/Courses/ip00/proj/Dithering1/image/lena%20average.gif
de loin, tu crois qu´il y a des nuances de gris, et bien de pres, tu vois que c´est juste des points noirs purs et blancs purs, et que le fait de les mélanger astucieusement donne l´illusion, de loin, d´avoir du gris ! c´est du dithering, c´est simuler des couleurs supplémentaires ![]()
--> les imprimantes marchent comme ça encore
mais avant, quand on bossait en 8 bpp, CT courant ![]()
lag-it > ![]()