[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ns] [Fwd: Help with my X11 program]



 
-- 
********************************
*  Emmanuel A Jammeh           *
*  Postgrad Research  Student  *
*  University of Essex         *
*  Colchester CO4 3SQ          *
*  England                     *
*                              *
*  Tel:   00 44 1206 53 7101   *
*  email: [email protected]   *
*         [email protected]   *
********************************
 


Hello,
I am a postgrad student at the university of essex in the video networking lab. I am not much of
a programmer and i have been grappling with a programming problem.


I am trying to develop an mpeg frame display using X11. The program only works
on 8 bit displays, but my computer is a 24 bit truecolor.


I will be most grateful if you can look at my program and help me make it display
on 24 bit truecolor.


I can perfectly display images on 8 bit displays


Thank you








********************************
*  Emmanuel A Jammeh           *
*  Postgrad Research  Student  *
*  University of Essex         *
*  Colchester CO4 3SQ          *
*  England                     *
*                              *
*  Tel:   00 44 1206 53 7101   *
*  email: [email protected]   *
*         [email protected]   *
********************************
 
#include <stdio.h>
#include <stdlib.h>
//#include "global.h"

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <sys/time.h>

void init_display (char *name);
void exit_display (void);
void display_second_field (void);
void dither (unsigned char *src[]);
void init_dither (void);


/* private prototypes */
 void display_image (XImage *ximage, unsigned char *dithered_image);
 void ditherframe (unsigned char *src[]);
void my_error(char* message);
 void doframerate();

/* local data */
 unsigned char *dithered_image, *dithered_image2;
 unsigned char ytab[256+16];
 unsigned char utab[128+16];
 unsigned char vtab[128+16];
 int convmat[8][4]=
{
  {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
  {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
  {104597, 132201, 25675, 53279}, /* unspecified */
  {104597, 132201, 25675, 53279}, /* reserved */
  {104448, 132798, 24759, 53109}, /* FCC */
  {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
  {104597, 132201, 25675, 53279}, /* SMPTE 170M */
  {117579, 136230, 16907, 35559}  /* SMPTE 240M (1987) */
};
 int matrix_coefficients=5;

/* X11 related variables */
 Display *display;
 Window window;
 GC gc;
 XImage *ximage, *ximage2;
 unsigned char pixel[256];
 unsigned char *clp;
 int width=352, height=288, chrom_width=176, chrom_height=144;
 int framerate = 25;
 struct timeval tftarget;
/*____________________________________________________________________________________*/

main(int argc, char* argv[])
{
  int i,j;
  FILE *fd;
  char fname[255];
  unsigned char* frame[400][3];
  int maxFrameNum,minFrameNum;
  unsigned char *showframe;
  
  if (argc<4)
    {
      fprintf(stderr,"\n\nSyntax: %s  InpurSeq  From  To [width height framerate]\n\n",argv[0]);
      exit(0);
    }
  
  // clip table 
  if (!(clp=(unsigned char *)malloc(1024))) exit(0);
  clp += 384;

  for (i=-384; i<640; i++) clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
  
  minFrameNum = atoi(argv[2]);
  maxFrameNum = atoi(argv[3]);
  
  showframe = (unsigned char *) malloc (maxFrameNum-minFrameNum+1);

  //memory for the frames
  for (i=0;i<maxFrameNum-minFrameNum+1;i++)
    {
      if (!(frame[i][0] = (unsigned char*)malloc(width*height)))  error("MallocFailed");
      if (!(frame[i][1] = (unsigned char*)malloc(width*height/4)))error("MallocFailed");
      if (!(frame[i][2] = (unsigned char*)malloc(width*height/4)))error("MallocFailed");
      showframe[i]=1;
    }

  if (argc==7)
    {
      width =atoi(argv[4]); chrom_width =width >>1;
      height=atoi(argv[5]); chrom_height=height>>1;
      framerate=atoi(argv[6]);
    }
  else
    printf("\nWarning: Width=%d Height=%d Framerate = %d \n\n",width,height,framerate);
  
  init_display(argv[1]);   //initialise the display
  init_dither();           // initialise the dither

  //load the frames 
  printf("\nLoading Frames to memory..\n");
  for (j=0, i=minFrameNum; i<maxFrameNum,j<maxFrameNum-minFrameNum+1; i++, j++)
    {
      sprintf(fname,"%s%03d.yuv",argv[1],i);

      if (!(fd = fopen(fname,"rb")))
	{
	  printf("<%s not found>\n",fname);
	  showframe[i]=0;
	  continue;
	}
      fread(frame[j][0],1,width*height,fd);
      fread(frame[j][1],1,width*height/4,fd);
      fread(frame[j][2],1,width*height/4,fd);
      fclose(fd);
      printf("<%d>",i);fflush(stdout);
    }
  
  do
    {
      gettimeofday(&tftarget,(struct timezone *)NULL);
      //display the frames
      for (i=0;i<maxFrameNum-minFrameNum+1;i++)
	{
	  if (showframe[i])
	    {
	      dither(frame[i]);
	      doframerate();
	    }
	}
    }while (1);
  
}// end of main



/* connect to server, create and map window,
 * allocate colors and (shared) memory
 */
void init_display(char *name)
{
  int crv, cbu, cgu, cgv;
  int y, u, v, r, g, b;
  int i;
  char dummy;
  int screen;
  Colormap cmap;
  int private;
  XColor xcolor;
  unsigned int fg, bg;
  char *hello = name;
  XSizeHints hint;
  XVisualInfo vinfo;
  XEvent xev;
  unsigned long tmp_pixel;
  XWindowAttributes xwa;

  display = XOpenDisplay("");

  if (display == NULL)
    my_error("Can not open display\n");

  screen = DefaultScreen(display);

  hint.x = 200;
  hint.y = 200;
  hint.width = width;
  hint.height = height;
  hint.flags = PPosition | PSize;
  
  /* Get some colors */
  
  bg = WhitePixel (display, screen);
  fg = BlackPixel (display, screen);
  
  /* Make the window */
  
  if (!XMatchVisualInfo(display, screen, 8, PseudoColor, &vinfo))
    {
      if (!XMatchVisualInfo(display, screen, 8, GrayScale, &vinfo)) 
	my_error("requires 8 bit display\n");
    }
  
  window = XCreateSimpleWindow (display, DefaultRootWindow (display),
             hint.x, hint.y, hint.width, hint.height, 4, fg, bg);

  XSelectInput(display, window, StructureNotifyMask);

  /* Tell other applications about this window */

  XSetStandardProperties (display, window, hello, hello, None, NULL, 0, &hint);

  /* Map window. */

  XMapWindow(display, window);

  /* Wait for map. */
  do
  {
    XNextEvent(display, &xev);
  }
  while (xev.type != MapNotify || xev.xmap.event != window);

  XSelectInput(display, window, NoEventMask);

  /* matrix coefficients */
  crv = convmat[matrix_coefficients][0];
  cbu = convmat[matrix_coefficients][1];
  cgu = convmat[matrix_coefficients][2];
  cgv = convmat[matrix_coefficients][3];

  /* allocate colors */

  gc = DefaultGC(display, screen);
  cmap = DefaultColormap(display, screen);
  private = 0;

  /* color allocation:
   * i is the (internal) 8 bit color number, it consists of separate
   * bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000
   * and yyyy=1111, this leaves 32 colors for other applications
   *
   * the allocated colors correspond to the following Y, U and V values:
   * Y:   24, 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232
   * U,V: -48, -16, 16, 48
   *
   * U and V values span only about half the color space; this gives
   * usually much better quality, although highly saturated colors can
   * not be displayed properly
   *
   * translation to R,G,B is implicitly done by the color look-up table
   */

  for (i=16; i<240; i++)
    {
      /* color space conversion */
      y = 16*((i>>4)&15) + 8;
      u = 32*((i>>2)&3)  - 48;
      v = 32*(i&3)       - 48;
      
      y = 76309 * (y - 16); /* (255/219)*65536 */
      
      r = clp[(y + crv*v + 32768)>>16];
      g = clp[(y - cgu*u -cgv*v + 32768)>>16];
      b = clp[(y + cbu*u + 32786)>>16];
      
      /* X11 colors are 16 bit */
      xcolor.red   = r << 8;
      xcolor.green = g << 8;
      xcolor.blue  = b << 8;
      
      if (XAllocColor(display, cmap, &xcolor) != 0)
	pixel[i] = xcolor.pixel;
      else
	{
	  /* allocation failed, have to use a private colormap */
	  
	  if (private)
	    my_error("Couldn't allocate private colormap");
	  
	  private = 1;
	  
	  
	  /*fprintf(stderr, "Using private colormap (%d colors were available).\n",
	    i-16);*/
	  
	  /* Free colors. */
	  while (--i >= 16)
	    {
	      tmp_pixel = pixel[i]; /* because XFreeColors expects unsigned long */
	      XFreeColors(display, cmap, &tmp_pixel, 1, 0);
	    }
	  
	  /* i is now 15, this restarts the outer loop */
	  
	  /* create private colormap */
	  
	  XGetWindowAttributes(display, window, &xwa);
	  cmap = XCreateColormap(display, window, xwa.visual, AllocNone);
	  XSetWindowColormap(display, window, cmap);
	}
    }
  
  
  
  ximage = XCreateImage(display,None,8,ZPixmap,0,&dummy,
			width,height,8,0);
  
  if (!(dithered_image = (unsigned char *)malloc(width* height)))
    my_error("malloc failed");
}



void exit_display()
{

}

void display_image(ximage,dithered_image)
     XImage *ximage;
     unsigned char *dithered_image;
{
  /* display dithered image */
  ximage->data = (char *) dithered_image;
  XPutImage(display, window, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
}

void display_second_field()
{
  display_image(ximage2,dithered_image2);
}

/* 4x4 ordered dither
 *
 * threshold pattern:
 *   0  8  2 10
 *  12  4 14  6
 *   3 11  1  9
 *  15  7 13  5
 */

void init_dither()
{
  int i, v;
  
  for (i=-8; i<256+8; i++)
    {
      v = i>>4;
      if (v<1)
	v = 1;
      else if (v>14)
	v = 14;
      ytab[i+8] = v<<4;
    }

  for (i=0; i<128+16; i++)
    {
      v = (i-40)>>4;
      if (v<0)
	v = 0;
      else if (v>3)
	v = 3;
      utab[i] = v<<2;
      vtab[i] = v;
    }
}


void dither(src)
     unsigned char *src[];
{
  ditherframe(src);
  display_image(ximage,dithered_image);
}

void ditherframe(src)
     unsigned char *src[];
{
  int i,j;
  int y,u,v;
  unsigned char *py,*pu,*pv,*dst;
  int chroma_format=1;
  int CHROMA444 = 2, CHROMA420 = 1;

  
  py = src[0];
  pu = src[1];
  pv = src[2];
  dst = dithered_image;
  
  for (j=0; j<height; j+=4)
    {
      /* line j + 0 */
      for (i=0; i<width; i+=4)
	{
	  y = *py++;
	  u = *pu++ >> 1;
	  v = *pv++ >> 1;
	  *dst++ = pixel[ytab[y]|utab[u]|vtab[v]];
	  y = *py++;

	  if (chroma_format==CHROMA444)
	    {
	      u = *pu++ >> 1;
	      v = *pv++ >> 1;
	    }
	  
	  *dst++ = pixel[ytab[y+8]|utab[u+8]|vtab[v+8]];
	  y = *py++;
	  u = *pu++ >> 1;
	  v = *pv++ >> 1;
	  *dst++ = pixel[ytab[y+2]|utab[u+2]|vtab[v+2]];
	  y = *py++;

	  if (chroma_format==CHROMA444)
	    {
	      u = *pu++ >> 1;
	      v = *pv++ >> 1;
	    }
	  
	  *dst++ = pixel[ytab[y+10]|utab[u+10]|vtab[v+10]];
	}
      
      if (chroma_format==CHROMA420)
	{
	  pu -= chrom_width;
	  pv -= chrom_width;
	}
      
      /* line j + 1 */
      for (i=0; i<width; i+=4)
	{
	  y = *py++;
	  u = *pu++ >> 1;
	  v = *pv++ >> 1;
	  *dst++ = pixel[ytab[y+12]|utab[u+12]|vtab[v+12]];
	  y = *py++;

	  if (chroma_format==CHROMA444)
	    {
	      u = *pu++ >> 1;
	      v = *pv++ >> 1;
	    }
	  
	  *dst++ = pixel[ytab[y+4]|utab[u+4]|vtab[v+4]];
	  y = *py++;
	  u = *pu++ >> 1;
	  v = *pv++ >> 1;
	  *dst++ = pixel[ytab[y+14]|utab[u+14]|vtab[v+14]];
	  y = *py++;
	  
	  if (chroma_format==CHROMA444)
	    {
	      u = *pu++ >> 1;
	      v = *pv++ >> 1;
	    }
	  
	  *dst++ = pixel[ytab[y+6]|utab[u+6]|vtab[v+6]];
	}
      
      /* line j + 2 */
      for (i=0; i<width; i+=4)
	{
	  y = *py++;
	  u = *pu++ >> 1;
	  v = *pv++ >> 1;
	  *dst++ = pixel[ytab[y+3]|utab[u+3]|vtab[v+3]];
	  y = *py++;
	  
	  if (chroma_format==CHROMA444)
	    {
	      u = *pu++ >> 1;
	      v = *pv++ >> 1;
	    }
	  
	  *dst++ = pixel[ytab[y+11]|utab[u+11]|vtab[v+11]];
	  y = *py++;
	  u = *pu++ >> 1;
	  v = *pv++ >> 1;
	  *dst++ = pixel[ytab[y+1]|utab[u+1]|vtab[v+1]];
	  y = *py++;
	  
	  if (chroma_format==CHROMA444)
	    {
	      u = *pu++ >> 1;
	      v = *pv++ >> 1;
	    }
	  *dst++ = pixel[ytab[y+9]|utab[u+9]|vtab[v+9]];
	}
      
      if (chroma_format==CHROMA420)
	{
	  pu -= chrom_width;
	  pv -= chrom_width;
	}
      
      /* line j + 3 */
      for (i=0; i<width; i+=4)
	{
	  y = *py++;
	  u = *pu++ >> 1;
	  v = *pv++ >> 1;
	  *dst++ = pixel[ytab[y+15]|utab[u+15]|vtab[v+15]];
	  y = *py++;
	  
	  if (chroma_format==CHROMA444)
	    {
	      u = *pu++ >> 1;
	      v = *pv++ >> 1;
	    }
	  
	  *dst++ = pixel[ytab[y+7]|utab[u+7]|vtab[v+7]];
	  y = *py++;
	  u = *pu++ >> 1;
	  v = *pv++ >> 1;
	  *dst++ = pixel[ytab[y+13]|utab[u+13]|vtab[v+13]];
	  y = *py++;
	  
	  if (chroma_format==CHROMA444)
	    {
	      u = *pu++ >> 1;
	      v = *pv++ >> 1;
	    }
	  
	  *dst++ = pixel[ytab[y+5]|utab[u+5]|vtab[v+5]];
	}
    }
}


void my_error(char* message)
{
  printf("\n\n%s\n\n",message);
  exit(0);
}

void doframerate()
{
  struct timeval tfdiff;
  const float REF_FRAME_RATE = /*29.97*/ 25.0; /*tjshan: changed by tamer */
  
  tftarget.tv_usec += 1000000 / framerate;
  
  /* this is where we should be */
  if (tftarget.tv_usec >= 1000000)
    {
      tftarget.tv_usec -= 1000000;
      tftarget.tv_sec++;
    }

  /* this is where we are */
  gettimeofday(&tfdiff,(struct timezone *)NULL);
  
  tfdiff.tv_usec = tftarget.tv_usec - tfdiff.tv_usec;
  tfdiff.tv_sec  = tftarget.tv_sec  - tfdiff.tv_sec;

  if (tfdiff.tv_usec < 0)
    {
      tfdiff.tv_usec += 1000000;
      tfdiff.tv_sec--;
    }
  
  /* See if we are already lagging behind */
  if (tfdiff.tv_sec < 0 || (tfdiff.tv_sec == 0 && tfdiff.tv_usec <= 0))
    return;
  
  /* Spin for awhile */
  select(0,NULL,NULL,NULL,&tfdiff);
}