Xlib : affichage d'image en mode 24 bits erroné

Xlib : affichage d'image en mode 24 bits erroné - C - Programmation

Marsh Posté le 11-09-2006 à 09:15:22    

bonjour,
Je rencontre quelques problèmes au niveau de l'affichage d'images avec la XLib. Jusque maintenant, mon programme fonctionnait avec des images 16 bits, et il fonctionnait très bien. A cause d'une limitation du serveur X, je ne peux pas afficher des images 16 bits lorsque le serveur est en mode 24 bits. J'ai donc tenté de modifier mes images en 24 bits, mais j'ai un problème d'affichage que je n'arrive pas à résoudre. L'image apparait brouillée, comme si le mode (16/24/32) n'était pas le bon. J'ai essayé toutes les combinaisons, sans succès.
 
 
Voici le code source que j'ai créé pour tester ca :  
 

Code :
  1. #include <X11/Xlib.h>
  2. #include <X11/Xutil.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. int main() {
  6. Display * display;
  7. Window   window;
  8. if (XInitThreads() == 0)    {
  9.  printf("Error : initializing XInitThreads.\n" );
  10.  return 1;
  11. }
  12. display = XOpenDisplay(NULL);
  13. if (display == NULL) {
  14.  printf("Error : Cannot open display.\n" );
  15. }
  16. window = XCreateSimpleWindow(display,XDefaultRootWindow(display),0,0,800,600,0,0,0);
  17. XSelectInput(display,window,ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask );
  18. XMapWindow(display,window);
  19. // charger l'image
  20. FILE *f;
  21. int x=0,y=0;
  22. char *buffer=NULL;
  23. f = fopen("test.raw","rb" );
  24. if (f == NULL) {
  25.  printf("Error : loading image.\n" );
  26. }
  27. else {
  28.  fread(&x,4,1,f);
  29.  fread(&y,4,1,f);
  30.  buffer = malloc(x*y*3);
  31.  if (buffer == NULL){
  32.   printf("Error : malloc\n" );
  33.  }
  34.  else {
  35.   fread(buffer,x*y*3,1,f);
  36.  }
  37.  fclose(f);
  38. }
  39. XImage *image = NULL;
  40. if (buffer) {
  41.  image = XCreateImage(display, DefaultVisual(display,DefaultScreen(display)),24,ZPixmap,0,buffer,x,y,8,0);
  42. }
  43. int running = 1;
  44. while (running) {
  45.  XEvent event;
  46.  XNextEvent(display,&event);
  47.  switch (event.type) {
  48.   case ButtonPress :
  49.   if (image) {
  50.    XLockDisplay(display);
  51.    XPutImage(display,window,DefaultGC(display,DefaultScreen(display)),image,0,0,event.xbutton.x,event.xbutton.y,x,y);
  52.    XSync(display,0);
  53.    XUnlockDisplay(display);
  54.   }
  55.   break;
  56.   case KeyPress :
  57.   running = 0; // quitter
  58.   break;
  59.  }
  60. }
  61. if (image) {
  62.  XDestroyImage(image);
  63. }
  64. XUnmapWindow(display,window);
  65. XDestroyWindow(display,window);
  66. return 0;
  67. }


 
A chaque clic de souris, il va afficher l'image test.raw que l'on peut trouver ici : http://xifedi.free.fr/test.raw
 
(format de l 'image tres simple : les 4 premiers octets forment la largeur, les 4 suivants la hauteur, et ensuite les valeurs RGB de l'image dans l'ordre RGB).
 
Je n'ai pas bien compris à quoi servent les 3 derniers paramètres de la fonction XCreateSimpleWindow, ainsi que les 2 derniers paramètres de la fonction XCreateImage. Peut-être ça vient de là ?
 
Ce code fonctionne très bien avec des images 16 bits , et en remplaçant le 24 par 16 dans le 3ème paramètre de XCreateImage. Par contre, il est nécessaire de passer le serveur X en mode 16 bits.
 
Merci d'avance pour vos réponses  :jap:

Reply

Marsh Posté le 11-09-2006 à 09:15:22   

Reply

Marsh Posté le 13-09-2006 à 06:49:00    

Vérifie les deux derniers arguments de XCreateImage:
 

  • bitmap_pad

Specifies the quantum of a scanline (8, 16, or 32). In other words, the start of one scanline is separated in client memory from the start of the next scanline by an integer multiple of this many bits.
 

  • bytes_per_line

Specifies the number of bytes in the client image between the start of one scanline and the start of the next.

Reply

Marsh Posté le 13-09-2006 à 08:44:21    

Bonjour,
 
j'ai résolu mon problème.
 
En fait, lorsqu'on est en mode 24 bits sous le serveur X, il ne faut pas fournir des images 24 bits, mais 32 bits. Pire que ca, il faut quand meme appeler la fonction XCreateImage, avec une profondeur de 24 bits (avec 32 ca ne marche pas), mais un pointeur qui contient l'image avec des pixels sur 32 bits.
 
Evidemment, ce n'est pas documenté.

Reply

Marsh Posté le 13-09-2006 à 21:30:05    

> Evidemment, ce n'est pas documenté.
Ben non!!! vérifie les options passées à XCreateImage.
J'ai comme l'impression que bitmap_pad=8 te rajoute 8 bits par pixels. Remarque que ça fait un bout de temps que j'ai pas essayé de faire un programme X11, mais autant que je me souvienne j'étais très impressionné par la rigueur du protocole.

Reply

Sujets relatifs:

Leave a Replay

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