/* --- samplen.c    ver1.1 */
/* originally coded by M. Hirasawa & T. Hasegawa 2001/04/13  */
/* revised by M. Oshima for size flexibility of image data file
   and to process Expose event */
/* -- warning: this prog. supports for 8 bit gray sun rasterfile
      and 8, 16, 24 bit XWindow display only */
/* --- last modification                      2002.06.30     */

/*  usage example samplen dome.ras */
/*  hit [enter] to continue
    press button on window to finish */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
/*          --- set image size here (file command or chimf.c is helpful ) */
/*          if you adopt *(data + y*width + x) instead to data[y][x],
            no need to define XMAX and YMAX                         */
#define         XMAX     160 /* for hirosue.ras */
#define         YMAX     120
/*#define         XMAX     720*/ /* for dome.ras */
/*#define         YMAX     486*/

static          Window                  root, win1, win2, wins[2];
static          Display                 *disp;
static          Visual                  *vis;
static          int                     deptho;
static          Colormap                cmap;
static          GC                      gc;
static          unsigned long          gray_lut[256];
/*static        unsigned short         gray_lut[256]; 2002.06.30 */

typedef struct{
  int magic; int width; int height; int depth; int length;
  int type; int maptype; int maplength;
}rasterfile;

rasterfile       raster;

char names1[] = "input image";
char names2[] = "output image";
int width, height, depthi;

/*void user_prog(u_char input_data[][XMAX], u_char output_data[][XMAX]
               , int width, int height);*/
void user_prog2(u_char *input_data, u_char *output_data, int width, int height);
u_char *get_image(char *);
unsigned int rev_word( unsigned int in);
XImage *mk_image(u_char *data, int width, int height, int depthi, int deptho);
Window make_win(char *name, int width, int height);
/*Window make_win(char *);*/
void graphic_intialize(void);
void evntloop(XImage *images[], Window wins[], int widtha[], int heighta[]);
/*void evntloop(XImage *images[], Window wins[]);*/


int main(int argc, char **argv)
{
  int i, j, x, y, t, k;
  u_char input_data[YMAX][XMAX], output_data[YMAX][XMAX];
  u_char *input_data0, *output_data0;
  char name[50];
  XImage *image1, *image2, *images[2];
  int widtha[2], heighta[2];
  float amp = 1.0;

  if( argc != 2 ){
    printf("Usage: %s [data_name]\n", argv[0]);
    exit(1);
  }

  name[0] = '\0';
  strcat(name, argv[1]);
  /* 画像用初期化 */
  graphic_intialize();
  /* width, height & depthi are set in get_image */
  input_data0 = get_image(name);
  widtha[0] = width;   heighta[0] = height;
  widtha[1] = width*3; heighta[1] = height*3;
  /* 入力データの設定 */
  t = 0;
  for(y =0; y < height; y++){
    for(x =0; x < width; x++, t++){
      k = *(input_data0+t) * amp;
      k = (k < 256) ? k : 255;
      input_data[y][x] = k;
    }
  }

  /* 入力画像表示用ウインドウの作成 */
  win1 = make_win(names1, width, height);
/*  win1 = make_win(names1);*/
  image1 = mk_image(&input_data[0][0], width, height, depthi, deptho);
  /*  image1 = mk_image(input_data, width, height, depthi, deptho);*/
  /* 入力イメージをウィンドウに表示 */
  XPutImage(disp, win1, gc, image1, 0, 0, 0, 0, width, height);
  XMapWindow(disp, win1);
  XFlush(disp);

  puts("Hit [Enter]!");
  getchar();

  /*  output_data = (u_char *)malloc(width * height * sizeof(u_char));*/

  /* ユーザプログラム */
  /* -- start ------------------------------------------------------- */

  user_prog2(&input_data[0][0], &output_data[0][0], width, height);
  /*  user_prog2(input_data0, output_data, width, height);*/

  /* -- end   ------------------------------------------------------- */

  /* 出力イメージ表示用ウィンドウの作成 */
  win2 = make_win(names2, width, height);
  /*  win2 = make_win(names2);*/
  /* 出力イメージをウィンドウに表示 */
  image2 = mk_image(&output_data[0][0], width, height, depthi, deptho);
  /*  image2 = mk_image(output_data, width, height, depthi, deptho);*/
  XPutImage(disp, win2, gc, image2, 0, 0, 0, 0, width, height);
  XMapWindow(disp, win2);
  XFlush(disp);

  /* 再描画用イベントマスクの設定 */
  XSelectInput(disp, win1, ExposureMask | ButtonPressMask );
  XSelectInput(disp, win2, ExposureMask | ButtonPressMask );
  images[0] = image1; images[1] = image2;
  wins[0] = win1; wins[1] = win2;
  fprintf(stderr, "goto event loop\n");
  /* イベント待ちループ */
  evntloop(images, wins, widtha, heighta);
  /*  evntloop(images, wins);*/

  /* 終了処理 */
  puts("Finish!");  /* "finish" */
  XDestroyImage(image1);
  XDestroyImage(image2);
  return 0;
}


/* -- user_prog start --------------------------------------------- */

/* void user_prog(u_char input_data[][XMAX], u_char output_data[][XMAX]
               , int width, int height)
{
  int x, y;

  for(y = 0; y < height; y++){
    for(x = 0; x < width; x++){
      output_data[y][x] = input_data[y][x];
    }
  }

}*/

/* -- user_prog end   --------------------------------------------- */

void user_prog2(u_char *input_data, u_char *output_data, int width, int height)
  /*          if you adopt *(data + y*width + x) instead to data[y][x],
            no need to define XMAX and YMAX                         */
  {
  int x, y;

  for(y = 0; y < height; y++){
    for(x = 0; x < width; x++){
      *(output_data + y * width + x) = *(input_data + y * width +x); /* 01.12.27
 */
/*    for(x = 0; x < width; x++, output_data++, input_data++){
      *output_data = *input_data; */
      /* output_data[y][x] = input_data[y][x]; */
    }
  }

}


u_char *get_image(char *name)
     /* 入力ファイルから画像データを読み込み、
        vdに格納する */
{
  char        *dummy;
  FILE        *fpin;
  u_char *vd;
  unsigned int magic, magic0 = 0x59a66a95, magicr0 = 0xa659956a; /* 2002.06.30 *
/

  fpin = fopen(name, "r");
  if(fpin == NULL){
    fprintf(stderr, "error: can't open %s!\n", name);
    exit(1);
  }

  fread(&raster, sizeof(raster), 1, fpin);
  magic  = raster.magic; /* 2002.06.26 */
  width  = raster.width;
  height = raster.height;
  depthi = raster.depth;
  if(magic != magic0){
    width  = rev_word(width );
    height = rev_word(height);
    depthi = rev_word(depthi);
  }

  dummy = (char *)malloc((unsigned)raster.maplength);
  fread(dummy, 1, raster.maplength, fpin );/* colormap is skipped and ignored */
  free(dummy);

  vd = (u_char*)malloc(width * height *sizeof(char)); /* 2001.07.03 */
  fread( vd, 1, width * height, fpin );

  fclose(fpin);
  return vd;
}

/*---------- rev_word ----------*/
unsigned int rev_word( unsigned int in){
  /* this is for reversing the byte order of the given word.
     coded by M. Oshima 2000.06.30 */
  int k;
  unsigned int t, out;

  out = 0;
  for(k = 0; k <= 3 ; k++){
    t = in >> (k * 8 ); /* take from right most */
    t = t & 255;
    out = out | ( t << ((3-k)*8) ); /* put on left most */
  }
  return out;
}


XImage *mk_image(u_char *data, int width, int height, int depthi, int deptho)
     /* 描画用データを作成する */
     /* input data depth is only supposed to be 8 bit */
     /* --- last modification 2002.06.30 */
{
  int dco, x, y, byte, pad;
  u_char *data0, *dto, *dto0;
  XImage *image;
  static long pixel;
  static char *pix_byte = (u_char *)(&pixel);

  data0 = data;
  dco = deptho / 8;
  if(!(dco >= 1 && dco <= 4)){ /* 8, 16, 24, 32 bit Displays are supported */
    fprintf(stderr, "output depth %d is not supported in mk_image\n",deptho);
    exit (1);
  }
  pad = (width * dco) % 4;
  if(pad != 0) pad = 4 - pad;
  dto0 = dto = (u_char *)malloc((unsigned)(width*dco+pad) * height);
  if(dto == NULL) exit(1);

  for(y = 0; y < height; y++){
    x = 0;
    while (x < width){
      pixel = gray_lut[*data];
      for(byte = 0; byte < dco; byte++, dto++){
        *dto = *(pix_byte + sizeof(pixel) - dco + byte);
      }
      x++; data++;
    }
    dto += pad;
  }
  dto = dto0; data = data0;
  image = XCreateImage(disp, vis, deptho, ZPixmap, 0, 0,
                       width, height, 32, width * dco);
  image->data = (char *)dto;
  image->bits_per_pixel = 8 * dco;
  image->byte_order = MSBFirst;
  image->bitmap_unit = 32;
  image->red_mask   = vis->red_mask;
  image->green_mask = vis->green_mask;
  image->blue_mask  = vis->blue_mask;
  return image;
}


Window make_win(char *name, int width, int height)
     /* 画像表示用ウインドウの作成 */
     /*Window make_win(char *name)*/
{
  Window win;

  win = XCreateSimpleWindow(disp, root, 100, 100, width, height, 2, 0, 0);
  XStoreName(disp, win, name);
  XMapWindow(disp, win);
  XFlush(disp);

  return win;
}

void graphic_intialize()
     /* 画像初期化 */
     /* --- last modification 2002.06.30 */
{
  short gray, r, g, b, keisu;
  XColor xc;

  disp  = XOpenDisplay(NULL);
  root  = RootWindow(disp, 0);
  vis   = DefaultVisual(disp, 0);
  deptho= DefaultDepth(disp, 0);

  gc    = XCreateGC(disp, root, 0, 0);
  cmap  = DefaultColormap(disp, 0);

  keisu = (256*256-1)/255; /* to correspond 255 with 65535 2001.07.03 */
  for(gray = 0; gray < 256; gray++){
        xc.red     = (unsigned)gray * keisu;
        xc.green   = (unsigned)gray * keisu;
        xc.blue    = (unsigned)gray * keisu;
    /*    xc.red   = (unsigned)gray << 8;
    xc.green = (unsigned)gray << 8;
    xc.blue  = (unsigned)gray << 8;*/

    XAllocColor(disp, cmap, &xc);
    gray_lut[gray] = xc.pixel;
    /*    gray_lut[gray] = (unsigned short)xc.pixel; 2002.06.30 */
  }
}

void evntloop(XImage *images[], Window wins[], int widtha[], int heighta[])
     /*void evntloop(XImage *images[], Window wins[])*/
     /* イベント待ちループ */
     /* --- last modification 2002.06.25 */
{
  XEvent event;
  Window win;
  XImage *image;
  int i;

  while(1){
    XNextEvent( disp, &event );
    switch( event.type ){
    case Expose :
      fprintf(stderr, "Expose event\n");
      win = event.xany.window;
      for(i=0; i < 2; i++){
        if(win == wins[i]){
          image = images[i];
          break;
        }
      }
      XPutImage(disp,win,gc,image,0,0,0,0,
                widtha[i],heighta[i]);
      /*              width,height);   2002.06.25*/
      XFlush(disp);
      break;
    case ButtonPress :
      fprintf(stderr, "ButtonPress event\n");
      goto lpout;
    }
  }

lpout:

}



戻る