[C] MLX: Acceder aux différents octets d'un unsigned long

MLX: Acceder aux différents octets d'un unsigned long [C] - C - Programmation

Marsh Posté le 10-01-2012 à 10:48:39    

Salut, je taff en ce moment sur la MLX et j'utilise mlx_get_color_value pour récupérer un unsigned long img_color (qui est codé sur 4 octets) et qui correspond a ma couleur.
Pour donner cette couleurs a mon image, je dois copier le contenu de l'octet 1 de l'unsigned long dans le 1er octet de l'image, le contenu de l'octet 2 dans le 2e octet de l'image, l'octet 3 de l'unsigned long dans l'octet 3 de l'image. et ainsi de suite pour donner la couleur voulue à mes pixels.
 
Sauf que j'aimerais bien savoir comment accéder à chaque octets de l'unsigned long pour copier son contenu dans les octets de mon image ???
 
Merci d'avance

Reply

Marsh Posté le 10-01-2012 à 10:48:39   

Reply

Marsh Posté le 10-01-2012 à 11:13:24    

Bonjour,
 
Utilise les opérateur de bits :  
& pour appliquer un masque et isoler l'octet qui t'intéresse, et >> pour le ramener sur l'octet de poids faible :
 
exemple :
 

Code :
  1. unsigned long ma_couleur = 42;
  2. /* Extraction de l'octet le plus à gauche */
  3. unsigned char color1 = ( ma_couleur & 0xFF000000 ) >> 24;
  4. /* Extraction de la couleur dans le second octet */
  5. unsigned char color2 = ( ma_couleur & 0x00FF0000 ) >> 16;


etc...

Reply

Marsh Posté le 10-01-2012 à 11:41:26    

Merci,
apparement cela fonctionne, mais mal ...
 

Code :
  1. #include        <mlx.h>
  2. #include        "my_put.h"
  3. #include        <stdlib.h>
  4. #include        <stdio.h>
  5. void    my_pixel_put_to_image(unsigned long img_color, char *data, int sizeline, int bpp, int x, int y)
  6. {
  7.   int i;
  8.   unsigned char color1;
  9.   unsigned char color2;
  10.   unsigned char color3;
  11.   color1 = (img_color & 0xFF00000) >> 24;
  12.   color2 = (img_color & 0xFF00000) >> 16;
  13.   color3 = (img_color & 0xFF00000) >> 8;
  14.   data[y * sizeline + x * bpp / 8 ] = color1;
  15.   data[y * sizeline + x * bpp / 8 + 1] = color2;
  16.   data[y * sizeline + x * bpp / 8 + 2] = color3;
  17. }
  18. int     main()
  19. {
  20.   void  *mlx_ptr;
  21.   void  *win_ptr;
  22.   void  *img_ptr;
  23.   char  *data;
  24.   int   bpp;
  25.   int   sizeline;
  26.   int   endian;
  27.   unsigned long img_color;
  28.   int   z;
  29.   int   y;
  30.   z = 0;
  31.   y = 0;
  32.   mlx_ptr = mlx_init();
  33.   img_ptr = mlx_new_image(mlx_ptr, 500, 500);
  34.   data = mlx_get_data_addr(img_ptr, &bpp, &sizeline, &endian);
  35.   img_color = mlx_get_color_value(mlx_ptr, 0xf8f8ff);
  36.   while (z < 500)
  37.     {
  38.       my_pixel_put_to_image(img_color, data, sizeline, bpp, z, y);
  39.       z++;
  40.       if (z == 500 && y < 500)
  41.         {
  42.           z = 0;
  43.           y++;
  44.         }
  45.     }
  46.   win_ptr = mlx_new_window(mlx_ptr, 500, 500, "WOLF SUCK A LOT !" );
  47.   mlx_put_image_to_window(mlx_ptr, win_ptr, img_ptr, 0, 0);
  48.   while (42)
  49.     {
  50.     }
  51. }


 
Donc la j'envoie a get_color_value : 0xf8f8ff qui est equivalent à  { "ghostwhite" , 0xf8f8ff }, dans le fichier RGB de la mlx, donc en théorie sa doit me sortir du blanc mais avec ce code sa me sort du vert fluo... ? :s  
 

Reply

Marsh Posté le 10-01-2012 à 11:49:16    

Ligne 13 : je crois qu'il manque un 0 dans ton 0xFF00000 (le nombre de 0 devrait être pair)
Lignes 14 et 15 : tu as oublié de décaler le FF, parce que là tu extrais toujours la même couleur (boiteuse, en plus, car à cheval sur deux octets).

Reply

Marsh Posté le 10-01-2012 à 11:54:16    

Je comprend pas pour les lignes 14 et 15, comment je peut extraire la meme couleurs alors que j'y soustrais des octets differents ?

Reply

Marsh Posté le 10-01-2012 à 12:10:54    

Bon, je reprends : mettons que img_color contienne 0xAABBCCDD.
AA est la couleur 1, BB est la couleur 2, CC est la couleur 3.
 
Pour extraire une couleur, il faut masquer le reste de la variable, puis décaler la couleur vers l'octet de poids faible pour le stocker dans un unsigned char.
 
L'opération (img_color & 0xFF000000) a pour résultat 0xAA000000. On décale ensuite de 24 bits pour ramener l'octet AA sur l'octet de poids faible.
 
Pour extraire BB, on doit utiliser le masque 0xFF0000, car c'est le 3eme octet qui nous intéresse. Puis on décale de 16 bits.
 
Pour CC, on utilise le masque 0xFF00, et on décale de 8 bits.
 
C'est plus clair ?
 

Reply

Marsh Posté le 10-01-2012 à 13:00:15    

Ouai ok merci c'est plus clair :)

Reply

Marsh Posté le 10-01-2012 à 13:12:49    

Hum, j'ai toujours le même main, j'essaye de lui passer la couleur snow (0xfffafa)

 

et voila ma fonction pixel_put_to_image():

 
Code :
  1. void    my_pixel_put_to_image(unsigned long img_color, char *data, int sizeline, int bpp, int x, int y)
  2. {
  3.   unsigned char r;
  4.   unsigned char g;
  5.   unsigned char b;
  6.   r = ((img_color & 0xFF000000) >> 24);
  7.   g = ((img_color & 0xFF0000) >> 16);
  8.   b = ((img_color & 0xFF00) >> 8);
  9.   data[y / sizeline + x / bpp * 8 ] = b;
  10.   data[y / sizeline + x / bpp * 8 + 1] = g;
  11.   data[y / sizeline + x / bpp * 8 + 2] = r;
  12. }
 

Et ceci m'affiche un bleu un peu turquoise.
J'ai donc surement mal compris ce que tu a voulu me faire comprendre en faite ^^.


Message édité par Blobblob02 le 10-01-2012 à 13:45:07
Reply

Marsh Posté le 10-01-2012 à 13:24:43    

OK, je vois... Les exemples que je t'ai donné partaient du principe que les codes RGB étaient dans les octets de poids fort, et que l'octet de poids faible était réservé au canal alpha. Il fallait naturellement adapter à ton cas de figure.
 
A voir ton exemple, il faut que tu modifies tes masques et le nombre de bits de décalage :
R => 0xFF0000 et décalage de 16
G => 0xFF00 et décalage de 8
B => 0xFF et pas de décalage

Reply

Marsh Posté le 10-01-2012 à 13:43:55    

OK merci ça fonctionne :)

Reply

Marsh Posté le 10-01-2012 à 13:43:55   

Reply

Marsh Posté le 10-01-2012 à 16:37:30    

Et pourquoi pas
 

Code :
  1. unsigned char *src = (unsigned char *) &img_color;
  2. unsigned char r;
  3. unsigned char g;
  4. unsigned char b;
  5. r = src[0];
  6. g = src[1];
  7. b = src[2];


Reply

Marsh Posté le 10-01-2012 à 18:04:05    

jlnh a écrit :

Et pourquoi pas
 

Code :
  1. unsigned char *src = (unsigned char *) &img_color;
  2. unsigned char r;
  3. unsigned char g;
  4. unsigned char b;
  5. r = src[0];
  6. g = src[1];
  7. b = src[2];




 
http://fr.wikipedia.org/wiki/Endianness
 
Ton code ne donnera pas le même résultat suivant le CPU utilisé.
 
En plus de ça, tu forces "img_color" a être stocké en mémoire, là où la méthode avec masque et décalage permet de l'avoir dans un registre.

Reply

Marsh Posté le 10-01-2012 à 22:48:07    

Tu peux l'envoyer dans data directement sans passer
par r, g, b!
 
Plus élégant encore union/structure.

Message cité 1 fois
Message édité par jlnh le 10-01-2012 à 22:49:10
Reply

Marsh Posté le 11-01-2012 à 09:59:03    

jlnh a écrit :

Tu peux l'envoyer dans data directement sans passer
par r, g, b!
 
Plus élégant encore union/structure.


 
Ça résout pas le problème d'endianness.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed