/* --- visio.c ver1.4*/
/*      1997頃           長濱 剛 初期版
        ansi_win.c       橋爪 英樹      H9.6.24
        1999.07.20 改訂 大島正毅
        1999.08.16       大島正毅 revised. named visio.c for common use
        1999.09.20 updated on titan (struct rasin)
        1999.09.30 color rasterfile supported                 */
/*                             1st release(ver1.0)   1999.10.01  */
/*                             ver1.1   released     1999.10.13  */
/*                             ver1.1.1 released     1999.10.27  */
/*                             ver1.2   released     1999.11.12  */
/*                             ver1.2.2 released     2000.07.03  */
/*                             ver1.3   released     2000.08.07  */
/*                             ver1.3.1 released     2000.08.30  */
/*                             ver1.4   released     2001.06.14  */
/*                             last modification     2001.06.14  */


/*
References:
1.木下凌一:XWindow Ver.IIプログラミング、日刊工業新聞社
2.http://www.students.chiba-u.ac.jp/consultant/xlib/xlib0.html
3.man rasterfile (Sun OS)
4.柴山 守:X11による画像処理 基礎プログラミング、技術評論社
5.David C. Kay & John R. Levine: グラフィックファイル フォーマット ハンドブッ
ク、アスキー出版局
6.Olivwr Jones著、三浦明美・ドキュメントシステム訳:X Windowハンドブック、ア
スキ
ー出版局 */

#include "vissub.h"

#define DEBUG False

void tst_ptn(struct rasin *rasin);

/*   -------- get_image -------- */
/*                             last modification     2000.09.12  */
/*画像ファイルデータの読み込み*/
/* ヘッダ部を読み込み(ない場合(grayのとき)は作る)、colorデータを整え、
正味のラスターデータを読む   このシステムでは画像サイズはヘッダ等から
自動的に決める ユーザプログラムも配列等をコーディング段階で決めなくてよい */
struct rasin *get_image(char *data_name, int *width, int *height, int *pixs)
{
  int i;
  u_char *vdata, *vdata2, *vdisp;
  FILE *fpin;
  struct rasin *rasin;
  XColor *color, color_bw[2]; /* XColorはColormapの材料となるデータ */

  disp_set(); /* dispデータ等の設定 (mk_dircolで必要) 2000.09.12 */
  rasin = (struct rasin*)NULL;
  rasin = (struct rasin*)malloc(sizeof(struct rasin)); /* rasin領域の確保 */
  if(rasin == NULL) goto alcer;
  color = get_header(data_name, rasin);/* 画像ファイルからのヘッダの読み込み*/
  rasin->color = color; /* 2000.09.12 */
  if(rasin->no_cmp == False && color == NULL) goto alcer;

/* get_headerをcall後ディスクの位置は正味データの直前と仮定 */
  fpin = rasin->fpin;
  vdata = (u_char *)malloc(rasin->length); /*画像データ領域の確保*/
  if(vdata == NULL) goto alcer;
  rasin->vdata = vdata; vdisp = vdata;
  rasin->vdisp = vdisp;

  fread( vdata, sizeof(char), rasin->length , fpin ); /*画像データの読み込み*/
  fclose(fpin);

  if(rasin->byte_encoded == True){ /* byte_encoded形式データの場合 */
    vdata2 = decode_vdata(vdata, rasin);
    free(vdata);
    vdata = vdata2;
    rasin->vdata = vdata;
  }
/*    tst_ptn(rasin);*/
  *width = rasin->width; *height = rasin->height;
  *pixs = rasin->pixs; color = rasin->color;
  return rasin;
alcer:
  printf("alloc failed in get_iage\n");
  return NULL;
}

/* -------- get_header -------- */
/*                             last modification     2001.06.03 */
/* 画像ファイルからのヘッダの読み込み */
/* ---------------------------------------------- */
XColor
*get_header(char *data_name, struct rasin *rasin)
/* ---------------------------------------------- */
/*             --- last modification     2000.11.13 */
/* Sun rasterfile (icase =1,2), grayファイル(ヘッダなしの8ビット/画素データ)
(icase = 0) を想定*/ /* grayデータの場合(ヘッダなし)ダミーカラーマップ
作成、通常raster.ras_width等読み終わった後カラーマップを整える */
{
  int icase, i, j, pixs;
/*    char line[100];*/
  FILE *fpin; u_char *colbuf;
    u_char *vdata, *vdisp;
  XColor *color;
  unsigned int magic, magict = 0x59a66a95; /* 2000.06.30 */
  static XStandardColormap *scmap; /* 2000.10.11 */
/* definition of rasterfile is in vismain.h */

  color = (XColor *)NULL;
  fpin = fopen( data_name,"r" );
  if( fpin==NULL ){
    printf("Can't open %s.Abort!!\n",*data_name);
    return NULL;
  }
  rasin->fpin = fpin;
  rasin->nrm_magic    = rasin->rvs_magic = rasin->gray = rasin->no_cmp
    = rasin->byte_encoded =rasin->dir_col = False;
/*  = rasin->byte_encoded =rasin->color_data = False; 2000.10.11 */
  magic = getw(fpin);
  raster.ras_magic = magic;
/*  raster.ras_magic = getw(fpin);   2000.06.30 */
  icase = 0;
  if(magic == magict) {  /* ----- normal header is found */
    icase = 1;
    rasin->nrm_magic = True;
  } else{
    if(rev_word(magic) == magict){  /* ----- byte swap case */
      icase = 2;
      rasin->rvs_magic = True;
    }
  }
  if(icase == 0){
    /* --- magic is not found, gray data is assumed */
    rasin->gray = True;
    /* --- disk position is just before raster data */
    rewind(fpin);
    color = mk_psdhdr(data_name, rasin); /* grayデータ向けcolorデータの生成 */
    goto postproc;
  }

/*  ----- normal case: header data is effective */
/*        (magic or reverse magic is found)     */
/* --- to use struct rasterfile definition 2001.06.03 */
  rewind(fpin);
  fread(&raster, 1, sizeof(raster), fpin);

/*  raster.ras_width     = getw(fpin);    raster.ras_height    = getw(fpin);
  raster.ras_depth     = getw(fpin);    raster.ras_length    = getw(fpin);
  raster.ras_type      = getw(fpin);    raster.ras_maptype   = getw(fpin);
  raster.ras_maplength = getw(fpin); */

  if(rasin->rvs_magic == True){   /* --- 2000.07.02 ---*/
    raster.ras_width = rev_word(raster.ras_width); raster.ras_height
      = rev_word(raster.ras_height);
    raster.ras_depth = rev_word(raster.ras_depth); raster.ras_length
      = rev_word(raster.ras_length);
    raster.ras_type = rev_word(raster.ras_type); raster.ras_maptype
      = rev_word(raster.ras_maptype);
    raster.ras_maplength = rev_word(raster.ras_maplength);
  }
  pixs = raster.ras_maplength/3;
  rasin->width  = raster.ras_width ; rasin->height     = raster.ras_height;
  rasin->depth  = raster.ras_depth ; rasin->length = raster.ras_length;
  rasin->pixs       = pixs;  rasin->points = rasin->width * rasin->height;
  rasin->type      = raster.ras_type;       /* 2000.07.05 */
  rasin->maptype   = raster.ras_maptype; /* 2000.07.05 */
  rasin->maplength = raster.ras_maplength;  /* 2000.07.05 */
  if( !(rasin->depth == 1 || rasin->depth == 8 || rasin->depth == 24
        || rasin->depth == 32)){ /* 2000.08.30 32, 1 added */
    printf("depth %d is not supported currently by get_header\n",rasin->depth);
    goto postproc;
  }
  if(pixs > 256) {
    printf("--- pixs exceeds 256 in get_header\n");
    goto postproc;
  }
  /* --- for raster.ras_type: see /usr/include/rasterfile.h */
  if( !(raster.ras_type == RT_STANDARD || raster.ras_type == RT_BYTE_ENCODED
        || raster.ras_type == RT_FORMAT_RGB)){
    printf("ras_type %d is not supported by get_header\n",raster.ras_type);
    goto postproc;
  }
  if(pixs == 0) {
/*      --- no colormap on rasterfile */
    icase = 10;
    rasin->no_cmp     = True;
    rasin->dir_col    = True;
/*  rasin->color_data = True; 2000.10.11 */
    no_cmp(rasin);
    goto postproc;
  }

#define DEBUG False
#ifdef DEBUG
/*#if DEBUG*/
/*  printf("call mk_nrmcmp in get_header  pixs,rasin->dir_col %d %d\n"
         ,pixs,rasin->dir_col); */
#endif DEBUG
/*#endif*/
/*  pixs = raster.ras_maplength/3;  2000.09.07  rejected 2000.11.13 */
  fpin  = rasin->fpin;
  colbuf = set_colbuf(fpin, pixs); /* 2000.09.07 */
  /* 非ダイレクトrasterfile(カラーマップあり)向けcolorの処理  2000.11.13*/
  color = mk_nrmcmp(pixs, colbuf);
  rasin->color  = color ;
  rasin->colbuf = colbuf; /* 2000.11.13 */
/*  color = mk_nrmcmp(data_name, rasin);  2000.09.07 */
  goto postproc;

postproc:
/* ダイレクトカラーデータ(カラーマップなし)について、疑似的に8bit/pixel
向けカラーマップ材料colorを作る */
  if(rasin->dir_col == True && (rasin->depth == 1 || rasin->depth == 24
                                   || rasin->depth == 32 )
/*  if(rasin->color_data == True && (rasin->depth == 1 || rasin->depth == 24
2000.10.11 */
     ){
    color = mk_dircol(data_name, &scmap, rasin);
/*  color = mk_dircol(data_name, rasin); 2000.10.11 */
    rasin->color = color;
    rasin->scmap = scmap; /* 2000.10.11 */
  }
  return color;
alcer:
  printf("alloc failed in get_image\n");
  return NULL;
} /*---------- end of get_header ----------*/


/* ---------- no_cmp ---------- */
/* ---- coded by M. Oshima 2000.09.12 */
/* rasterfileがcolormapのないダイレクト形式の場合、画像データ読み出し
に必要なオフセット等を与える */
int
no_cmp(struct rasin *rasin)
{
  int pix_span, pix_offset, r_offset, g_offset, b_offset;

  if(rasin->depth == 24) { /* 2000.08.29 */
    pix_span = 3; pix_offset = 0;}
  else if(rasin->depth == 32){
    pix_span = 4; pix_offset = 1; /* 1st byte is ignored for 32 bit data */
  }
  if(rasin->type || RT_STANDARD){
    r_offset = 2; g_offset = 1; b_offset = 0;}
  else {
    r_offset = 0; g_offset = 1; b_offset = 2;
  }
  rasin->pix_span =pix_span; rasin->pix_offset = pix_offset;
  rasin->r_offset = r_offset; rasin->g_offset = g_offset;
  rasin->b_offset = b_offset;
/*       ----------------------- */
  if(raster.ras_type == RT_BYTE_ENCODED){
/*    icase =11; */
    rasin->byte_encoded = True;
  }
/*    goto postproc; 2000.09.12 */
}
/* ----------- end of no_cmp ---------- */


/*   -------- wrt_image -------- */
/*   this is for writing image data to disk in rasterfile format
     coded by M. Oshima 2000.07.04   */
/*                             last modification     2000.07.04  */
/*画像ファイルデータの書き込み*/
/* ヘッダ部を書き込み、colorデータを書き込み、正味のラスターデータを書く */
int wrt_image(char *data_name, u_char *vdata, int length, XColor *color
, int pixs, int width, int height, int depth, int type
, int maptype, int maplength, struct rasin *rasin)
/* , int maptype, int maplength) 2000.11.13 */
{
  FILE *fpin;

/* 画像ファイルへのヘッダの書き込み*/
  fpin = wrt_header(data_name, length, color, pixs, width, height
                    , depth, type, maptype, maplength, rasin);
/*                  , depth, type, maptype, maplength); 2000.11.13 */

/* wrt_headerをcall後ディスクの位置は正味データの直前と仮定 */
  fwrite( vdata, sizeof(char), length , fpin ); /*画像データの書き込み*/
  fclose(fpin);
  return SUCCESS;
}
/* -------- end of wrt_image -------- */


/* -------- wrt_header -------- */
/* coded by M. Oshima 2000.07.04 */
/*                             last modification     2000.11.13  */
/* 画像ファイルヘのヘッダの書き込み */
FILE *
wrt_header(char *data_name, int length, XColor *color, int pixs
, int width, int height, int depth, int type, int maptype, int maplength
, struct rasin *rasin)
/* , int width, int height, int depth, int type, int maptype
, int maplength) 2000.11.13 */
/* Sun rasterfile (icase =1,2), grayファイル(ヘッダなしの8ビット/画素データ)
(icase = 0) を想定、非ダイレクトカラー(カラーマップあり)も想定
(2000.11.13追加) */
{
  int icase, i, keisu, colmax = 255, t;
  double rkeisu;
  FILE *fpin;
  int magic = 0x59a66a95, r, g, b, rt, gt, bt;
  u_char colbufl[768], *colbuf;
  /*  u_char colbuf[768]; 2000.11.13 */

  fpin = fopen( data_name,"w" );
  if( fpin==NULL ){
    printf("Can't open %s in wrt_header.Abort!!\n",*data_name);
    return NULL;
  }
  raster.ras_magic  = magic  ; raster.ras_width     = width;
  raster.ras_height = height ; raster.ras_depth     = depth;
  raster.ras_length = length ; raster.ras_type      = type ;
  raster.ras_maptype= maptype; raster.ras_maplength = maplength;
  putw(raster.ras_magic, fpin);
  putw(raster.ras_width, fpin);    putw(raster.ras_height , fpin);
  putw(raster.ras_depth, fpin);    putw(raster.ras_length , fpin);
  putw(raster.ras_type , fpin);    putw(raster.ras_maptype, fpin);
  putw(raster.ras_maplength, fpin);
  keisu  = (256 * 256)/(colmax + 1);
  rkeisu = 1.0 / (double)keisu;
  if(pixs > 256){
/*  if(pixs > 255){ 2000.11.13 */
    printf("Abort in wrt_header because pixs > 256, pixs = %d\n", pixs);
    /* 2000.11.13 */
    return NULL;
  }
  if(maplength == 0){
/* if(maptype != RMT_NONE){ 2000.11.13 */
    /* 元のデータにカーラーマップがないとき(ダイレクトカラー) 2000.11.13 */
    for(i = 0; i < pixs; i++){
      rt = (color + i)->red;
      gt = (color + i)->green;
      bt = (color + i)->blue;
      r  = (int)((double)rt * rkeisu);
      g  = (int)((double)gt * rkeisu);
      b  = (int)((double)bt * rkeisu);
      *(colbufl +         i) = r; /* 2000.11.13 */
      *(colbufl +   pixs +i) = g;
      *(colbufl + 2*pixs +i) = b;
    }
    for(i = 0; i < pixs * 3; i++){
      t = (int) colbufl[i]; /* 2000.11.13 */
      putc(t, fpin);
    }
  }
  else { /* 非ダイレクトカラー(カラーマップあり)のとき 2000.11.13 */
    colbuf = rasin->colbuf;
    for(i=0; i < pixs * 3; i ++){
      t = (int) colbuf[i];
      putc(t, fpin);
    }
  }
  return fpin;
 alcer:
  printf("alloc failed in get_image\n");
  return NULL;
 postproc:
  return fpin;
}
/*---------- end of wrt_header ----------*/


/*---------- 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;
}

/* -------- set_colbuf -------- */
/* rasterfileのカラーマップ部分の読み込み */
/* supposed this func. is called after header data (raster.ras_width etc.)
 are read and the position is just before for colormap */
/* coded M. Oshima 2000.09.07 */
u_char *
set_colbuf(FILE *fpin, int pixs)
{
  u_char *colbuf;
  u_char t;
  int i, k, colmax;

  colbuf=(u_char *)malloc(pixs * 3);
  if(colbuf == NULL) goto alcer;
  for(k=0; k < pixs * 3; k ++){
    t = getc(fpin); /* read colormap data */
    *(colbuf+k) = t;
/*    printf("k, colbuf in set_colbuf = %d %p\n",k,colbuf); */
  }
  return colbuf;
alcer:
  printf("alloc failed in set_colbuf\n");
  return NULL;
}


/* -------- mk_nrmcmp -------- */
/* 標準的rasterfile(非ダイレクトカラー、カラーマップあり)向けcolorの処理 */
/* make colormap cmap needed for XWindow from Sun raster colormap */
/* sunrasterfile形式のカラーマップ(8ビットr*pixsの形式がr,g,bの順)
からXWindow形式のカラーデータ(XColor形式)を作る */
/* 従来、rasterfile中のカラーマップデータを読みだして、直接処理していたが、
読み出し部はcolbufに譲り、柔軟性を増した(rasterfile由来でないcolbufを与え
て処理できる)。 */
/*                             last modification     2000.12.28 */
XColor
/* -------------- */
*mk_nrmcmp(int pixs, u_char *colbuf)
/* -------------- */
/*XColor *mk_nrmcmp(char *data_name, struct rasin *rasin) 2000.09.07 */
{
  u_char t;
  int i, j, k, colmax,r,g,b,cr,cg,cb;
  int keisu,rt,gt,bt;
  XColor *color;

  color = (XColor *)malloc(pixs*sizeof(XColor));
  if(color == NULL) goto alcer;
  colmax = 255; /*  provisionally */
  keisu = (256*256)/(colmax+1); /* カラーマップデータ輝度値最大255
                                    をXサーバ最大輝度65535に対応させる*/
  for( i=0; i < pixs; i++ ) {
    r  = *(colbuf +         i);
    g  = *(colbuf +   pixs +i);
    b  = *(colbuf + 2*pixs +i);
    rt = keisu * (double)r;
    gt = keisu * (double)g;
    bt = keisu * (double)b;
    rt = (rt < 65535.0) ? rt : 65535.0;
    gt = (gt < 65535.0) ? gt : 65535.0;
    bt = (bt < 65535.0) ? bt : 65535.0;
    (color+i)->red   = (unsigned int)rt;
    (color+i)->green = (unsigned int)bt;
    (color+i)->blue  = (unsigned int)gt;
    (color+i)->pixel = i;
    (color+i)->flags = DoRed | DoGreen | DoBlue;
#define DEBUG False
#if DEBUG
    cr =(color+i)->red;
    cg =(color+i)->green;
    cb =(color+i)->blue;
    printf(
    "i,cr,cg,cb,rt,gt,bt,r,g,b in mk_nrmcmp=%d %d %d %d %f %f %f %d %d %d\n"
           ,i,cr,cg,cb,rt,gt,bt,r,g,b);
#endif
  }
/*  free(colbuf); 2000.11.13 */
  return color;
alcer:
  printf("alloc failed in mk_nrmcmp\n");
  return NULL;
}

/* -------- tst_ptn -------- */
/*                             last modification     1999.10.01  */
void tst_ptn(struct rasin *rasin){
  int i,j,z,points,width,height,x,y;
  u_char *vdisp;
  int divx = 18, divy = 12;

  points = rasin->points;
  width  = rasin->width;
  height = rasin->height;
  vdisp = rasin->vdisp;
  for(i = 0; i < points; i++) *vdisp =0;
  z = 0;
  for(i = 0; i < height; i+= height/divy){
    for(j = 0; j <width; j+=width/divx, z++){
      printf("i,j,z in tst_ptn= %d %d %d\n",i,j,z);
      for(y = 0; y< height/divy; y++){
        for(x = 0; x < width/divx ; x++){
          if((i+y)*width+(j+x) < points) *(vdisp+(i+y)*width+(j+x))
            = (u_char)((z < 216)? z : 0);
        }
      }
    }
  }
}


/* -------- mk_dircol -------- */
/* ダイレクトカラー向けcolorの処理(プライベートカラーマップ向け標準カラ
ーマップ形式データの生成) */
/* このシステムの表示はXWindowの8ビットカラーを想定しているので、24ビッ
トダイレクトカラー等から対応するXWindow向けcolorデータ(XColor : cmap
の材料)を作る。これを用いてプライベートカラーマップを生成する。ここで
XStandardColormap形式scmapも与える。*/
/* --- make color map for direct 24, 32 bit color data */
/*                             last modification     2000.12.28  */
/* --------------------------------------------- */
XColor
*mk_dircol(char *data_name, XStandardColormap **scmap, struct rasin *rasin)
/* *mk_dircol(char *data_name, struct rasin *rasin) 2000.10.11 */
/* --------------------------------------------- */
/*XColor *mk_dircmp(char *data_name, struct rasin *rasin) 2000.08.31*/
{
  u_char *vdata, *vdisp;
  unsigned long r, g, b, red_max, red_mult, green_max, green_mult
    , blue_max, blue_mult, base_pixel;
/*   unsigned long red_max=5, green_max=5, blue_max=5, red_mult=36
     , green_mult=6, blue_mult=1, base_pixel=0;*/
  int ri,gi,bi;
  unsigned long keisu_r, keisu_g, keisu_b, pix;
  int i, pixs, points; /* vdmax = 255, vdm2;*/
  static XColor *color; int scn = 0;
/*  static XStandardColormap *scmap; 2000.10.11 */
  static XStandardColormap scmapa[3] =
    {{NULL, 5, 36, 5, 6, 5, 1, 0}
    ,{NULL, 7, 32, 7, 4, 3, 1, 0}
    ,{NULL, 6, 35, 6, 5, 4, 1, 0}};
  int black, white; Colormap cmap;


  if(rasin->depth ==1){ /* 深さ1ビットの場合もユーザから同一に呼べるように
   ここで扱う 2000.08.31 */
    pixs =256;
    color = (XColor *)malloc(256*sizeof(XColor)); /* rasterfileの
      colorと等価なものを作る */
    if(color == NULL) goto alcer;
    rasin->color = color; rasin->pixs = pixs;
    black = BlackPixel(disp, 0); white = WhitePixel(disp, 0);
    color[black].pixel = black; color[white].pixel = white;
    cmap = DefaultColormap(disp, 0);
    XQueryColor(disp, cmap, &color[black]);
    XQueryColor(disp, cmap, &color[white]);
    return color;
  }

  *scmap = scmapa +scn;
/*  rasin->scmap = scmap; 2000.10.11 */
  red_max    = (*scmap)->red_max   ; red_mult   = (*scmap)->red_mult  ;
  green_max  = (*scmap)->green_max ; green_mult = (*scmap)->green_mult;
  blue_max   = (*scmap)->blue_max  ; blue_mult  = (*scmap)->blue_mult ;
  base_pixel = (*scmap)->base_pixel;

  pixs  = (red_max+1) * (green_max+1) * (blue_max+1);
  rasin->pixs = pixs;
  color = (XColor *)malloc(pixs*sizeof(XColor)); /* rasterfileのcolormapと等価な
ものを作る */
  if(color == NULL) goto alcer;
  rasin->color = color;

  keisu_r = (256*256) / (red_max  +1); /* red_max+1 mapped to 0-65532 */
/*   keisu_r = (256*256-1) / red_max  ; */ /* red_max+1 mapped to 0-65531 */
  keisu_g = (256*256) / (green_max+1);
  keisu_b = (256*256) / (blue_max +1);

  for(r = 0; r<= red_max; r++){
    for(g = 0; g <= green_max; g++){
      for(b = 0; b <= blue_max; b++){
        pix = base_pixel + r*red_mult + g*green_mult + b*blue_mult;
        if(pix > pixs-1) pix = pixs-1;
        color[(int)pix].red   = (unsigned short)(r * keisu_r);
        color[(int)pix].green = (unsigned short)(g * keisu_g);
        color[(int)pix].blue  = (unsigned short)(b * keisu_b);
        color[(int)pix].pixel = pix;
        color[(int)pix].flags = DoRed | DoGreen | DoBlue;
      }
    }
  }

  return color;
alcer:
  printf("alloc failed in mk_nrmcmp\n");
  return NULL;
}

/* ---------- data_to_disp ---------- */
/* ダイレクトカラーデータ向けにvdata(ダイレクトカラーデータ)からvdisp
データ(8ビット)を生成 */
/* ダイレクトカラーでは正味24ビットのデータが供給されるが、このシステム
はXWindowの8ビットカラーを想定しているので、8ビット/画素のデータを作る */
/*                             last modification     2000.12.04  */
u_char
*data_to_disp(u_char *vdata, int points, XStandardColormap *scmap
                     , int pixs, struct rasin *rasin){
  u_char *vdisp;
  int i, j, ri,gi,bi,pix_data,bwrev,out2;
  u_char b_w[2], out;
  u_char bit_mask[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  int vdmax = 255, vdm2, pix_span, pix_offset, r_offset, g_offset, b_offset;
  unsigned long r, g, b, red_max, green_max, blue_max, red_mult, green_mult
    , blue_mult, base_pixel, pix;
/*   unsigned long r, g, b, rmax=5, gmax=5, bmax=5, rmul=36, gmul=6, bmul=1, pix
;*/
  int x,y,x2,y2; int width, height, width2;

  if(rasin->depth ==1){ /* 深さ1ビットの場合もユーザから同一に呼べるように
  ここで扱う 2000.08.30 */
    vdisp = (u_char *)malloc(points);
    width  = rasin->width; height = rasin->height;
    width2 = width + (width % 8);
    if(vdisp == NULL) goto alcer;
    b_w[0] = BlackPixel(disp, 0); b_w[1] = WhitePixel(disp, 0);
    bwrev = 1;
    i =-1;
/*   各行の後にある冗長ビットをよける必要がある */
    for(y = 0; y <  height; y++){
      for(x = 0; x < width; x++){
        i++; j = y * width2 + x;
        pix_data = ((vdata[j / 8]) & bit_mask[j % 8]) >> (7 - (j % 8));
        if(bwrev == 1) pix_data = 1 - pix_data;
        out = b_w[pix_data]; out2 = out;
        *(vdisp + i) = out;
      }
    }
    return vdisp;
  }
  pix_span = rasin->pix_span;   pix_offset = rasin->pix_offset;
  r_offset   = rasin->r_offset  ; g_offset = rasin->g_offset;
  b_offset = rasin->b_offset; /* 2000.08.29 */
  vdisp = (u_char *)malloc(points);
  if(vdisp == NULL) goto alcer;
/*   vdm2 = (vdmax+1) * 2;*/
  red_max   = scmap->red_max  ; red_mult   = scmap->red_mult  ;
  green_max = scmap->green_max; green_mult = scmap->green_mult;
  blue_max  = scmap->blue_max ; blue_mult  = scmap->blue_mult ;
  base_pixel= scmap->base_pixel;
  for(i = 0; i < points; i++){
    ri = vdata[pix_span*i+pix_offset+r_offset];
    gi = vdata[pix_span*i+pix_offset+g_offset];
    bi = vdata[pix_span*i+pix_offset+b_offset];
    r = ri*(red_max  +1)/(vdmax+1); /* 0-rimax(vdmax)+1 mapped to 0-red_max+1 */
    g = gi*(green_max+1)/(vdmax+1);
    b = bi*(blue_max +1)/(vdmax+1);
    pix = base_pixel + r*red_mult + g*green_mult + b*blue_mult;
    if(pix > pixs-1) pix = pixs-1;
    *(vdisp+i) = (u_char)pix;
#define DEBUG False
#if DEBUG
    if(!(ri==0 && gi==0 && bi==0)) printf(
    "i,r,g,b,pix in data_to_disp = %d %d %d %d %d\n",i,r,g,b,pix);
#endif
  }
  return vdisp;
alcer:
  printf("alloc failed in mk_nrmcmp\n");
  return NULL;
}


/* ---------- decode_vdata ---------- */
/* this is dedicated process for byte_encoded data */
/*                             last modification     1999.10.27  */
u_char *decode_vdata(u_char *vdata, struct rasin *rasin){
  int i, j, k, width, height, points, M, N, Nsum;
  u_char *vdata2;

  width = rasin->width; height = rasin->height; points = width * height;
  vdata2=(u_char *)malloc(points * 3);
  if(vdata2 == NULL) goto alcer;
  j = 0; Nsum =0;
  for(i=0; i <rasin->length; i++){
#define DEBUG False
#if DEBUG
    if(i < 100 || i > rasin->ras_length-100 || i % 1000 ==0){
      printf(
    "in decode_vdata i,j,M,N,Nsum,vdata[i],vdata[i+1],vdata[i+2] = %d %d %d %d %
d %d %d %d\n"
             ,i,j,M,N,Nsum,vdata[i],vdata[i+1],vdata[i+2]);
      }
#endif
    M = N =0;
    if((unsigned int)vdata[i] != 128){
      vdata2[j++] = vdata[i];
      continue;
    } else{ /* vdata[i] = 128 */
      N = (unsigned int)vdata[i+1];
      if(N == 0){
        vdata2[j++] = vdata[i]; i++;
      }else{
        Nsum += N;
        M = (unsigned int)vdata[i+2];
        for(k=0; k <= N; k++){
          vdata2[j++] =(u_char)M;
        } /* end of k loop */
        i += 2;
      } /* end of else */
    } /* end of else */
  } /* end of for */
  if(j != points * 3) goto err2;
  return vdata2;
alcer: printf("allocation error in decode_vdata\n");
  return(u_char *)NULL;
err2:  printf("length error in decode_vdata  points*3 j = %d %d \n",
              points*3, j);
  return(u_char *)NULL;
}



/* -------- mk_psdhdr -------- */
/* grayデータ向けcolorデータの生成 */
/*  pseud header information is generated for gray data*/
/*                             last modification     1999.10.01  */
XColor *mk_psdhdr(char *data_name, struct rasin *rasin)
{

  int i, c, pixs;
  int width, height, depth, points, length;
  FILE *fpin;
  XColor *color;

  i = 0;
  fpin = rasin->fpin;
  while((c = getc(fpin)) != EOF){
    i++;}
  rewind(fpin);
  length = i;
/*      3:4 ratio is assumed */
  height = (int)((sqrt(3.0)*0.5)*sqrt((double)length)+0.1);
  width  = (4*height)/3;
  depth  = 8;
  rasin->width = width    ; rasin->height = height;
  rasin->depth = depth    ; rasin->points = length;
  rasin->length = length;
  pixs = 256;
  rasin->pixs = pixs;
  rasin->depth  = raster.ras_depth ;
/*      ----- make colormap for mono chrome data */
  color = mono_cmp(rasin);  /*2001.06.09*/
/*  rasin->color = color; */
  return color;
}


/*      ----- make colormap for mono chrome data */
XColor *mono_cmp(struct rasin *rasin){
  int i;
  XColor *color;

  color = (XColor *)malloc(256*sizeof(XColor));
  if(color == NULL) goto alcer;
  rasin->color = color;
  rasin->pixs  = 256;
  for(i=0; i < 256; i++) {
/* カラーマップデータ輝度値最大をXサーバ最大輝度に対応させる    0-255 -> 
0-6553
5*/
    (color+i)->red=(color+i)->green=(color+i)->blue = i*256;
    (color+i)->pixel = i;
    (color+i)->flags = DoRed | DoGreen | DoBlue;
  }
  return color;
 alcer:
  printf("alloc failed in mk_psdhdr\n");
  return NULL;
}


/* ------ disp_set ----- */
/* to set display */
/* coded by M. Oshima 2000.08.30 */
/* last modification  2000.08.30 */
int disp_set(void){
/*  int i, ga, gb, pa, pb, bwrev=0;
    XColor color2;
    unsigned long black, white;
    Colormap cmap;*/
  int bwrev=0; unsigned long black, white;
  XSetWindowAttributes att;
  XVisualInfo xvi;

/* check 256 color mode in this server*/
  disp = XOpenDisplay(NULL);
  if( !XMatchVisualInfo( disp, 0, 8, PseudoColor, &xvi)) {
    printf("no 256 color mode does not exist in this server\n");
    return 1;
  }
  root = RootWindow(disp, 0);
  gc   = XCreateGC(disp,root, 0, 0);
  white     = WhitePixel(disp, 0);
  black = BlackPixel(disp, 0);
  bwrev = 3;
  if(black ==   0 && white == 255) bwrev = 0;
/* make empty colormap */
  vis = XDefaultVisual(disp, 0);
/*  printf("visual class= %d\n",vis->class); */
}

#define DEBUG False
/* -------- set_cmap -------- */
/* colorデータからプライベートカラーマップの生成 */
/*                             last modification     2000.08.30  */
Colormap set_cmap(XColor *color, int pixs, struct rasin *rasin){ /* set color ma
p */
/*Colormap set_cmap(XColor *color, int pixs){ 2000.08.30 */
/*int set_cmap(Window win, XColor *color, int pixs)*/ /* set color map */
  Colormap cmap;

  if(rasin->depth == 1){ /* 深さ1ビットの場合もユーザから同一に呼べるように
  ここで扱う 2000.08.30 */
    cmap = DefaultColormap(disp, 0);
    return cmap;
  }

  if(pixs == 0 || color == NULL){
    printf("illegal input to set_cmap  pixs, color= %d, %p\n",pixs,color);
    return FAIL;
  }
  cmap = XCreateColormap( disp, root, vis, AllocAll);
  XStoreColors( disp, cmap, color, pixs);
  XInstallColormap(disp, cmap);
  return cmap;
}


/* -------- win_set -------- */
/*ウインドウの設定*/
/*                             last modification     2000.08.10  */
Window win_set(int width, int height, char *name, Colormap cmap)
/*Window win_set(int width, int height, char *name)*/
/* header data (as is in rasterfile) is necessary in advance */
{
  int n;
  char *name_return;
  Window win;
  XSetWindowAttributes att;
  XVisualInfo xvi;
  XWindowAttributes watt;

  att.colormap = cmap;
  win = XCreateWindow( disp, root, 10, 10, (unsigned int)width,
                      (unsigned int)height, 0, 8, InputOutput,
                      vis, CWColormap, &att);

/*    att.override_redirect = True;
      XChangeWindowAttributes(disp, win, CWOverrideRedirect, &att);*/
  att.backing_store = Always;
  XChangeWindowAttributes(disp, win, CWBackingStore, &att);
  XGetWindowAttributes(disp, win, &watt);
  XStoreName(disp,win,name);
  XFetchName(disp,win,&name_return);
  XMapWindow(disp,win);

  XFlush(disp);
  return win;
}


#define DEBUG False
/* ----- put_image -------- */ /*画像の表示*/
/* 8ビットピクセル値の配列で表された画像データをcolorに従って表示する */
/*                             last modification     1999.10.01  */
XImage *put_image(u_char *vdisp, int width, int height, int depth\
, Window win, XColor *color, int pixs, int gray)
/*, Window win, XColor *color, int pixs, int gray, int bwrev)*/
{
  int i,points,vdsp,vimg,v,vb,vd;
  static int init=0;
  unsigned long pix;
  u_char *vimage;
  XImage *image;

  gray =0;
  points = width * height;
  vimage = (u_char *)malloc(points);
  if(vimage == NULL) goto alcer;

#define DEBUG False
#if DEBUG
  printf("----- vimage in put_image\n");
#endif
  vb = -1;
  for(i=0; i< points; i++ ){
    vd = (int)*(vdisp+i);
    if(gray != 1){
      *(vimage+i) =(u_char)color[vd].pixel;
    } else {
      *(vimage+i) =(u_char)vd;
    }
#define DEBUG False
#if DEBUG
    if(i/width - ((i/width)/18)*18 == 0){
      v = (int)*(vimage+i); vimg = v; vdsp = (int)*(vdisp+i);
      pix =color[*(vdisp+i)].pixel;
      if(v !=vb) printf("i,vdsp,pix,vimg in put_image= %d %d %ld %d\n"
                        ,i,vdsp,pix,vimg);
      vb = v;}
#endif
#if DEBUG
    if(i/10 ==0) printf("\n");
    if(i/200 == 0) printf("\n i = %d\n",i);
       printf(" %d",*(vimage+i));
#endif
  }

  image =XCreateImage(disp,vis,depth,ZPixmap,0,
                      vimage,width,height,
                      depth,width);
  if(image == NULL){
    printf("XCreateImage failed in put_image\n");
    return NULL;
  }
  XPutImage(disp,win,gc,image,0,0,0,0,
            width,height);
  XFlush(disp);
  free(vimage);
  return image;
alcer:
  printf("alloc failed in put_image\n");
  return NULL;
}

/* ----- mk_image -------- */ /*画像の表示のためimageデータを作る 2001.06.14*/
/* 8ビットピクセル値の配列で表された画像データをcolorに従って表示する */
/*                             last modification     2001.06.14  */
XImage *mk_image(u_char *vdisp, int width, int height, int depth\
, Window win, XColor *color, int pixs, int gray)
{
  int i,points,vdsp,vimg,v,vb,vd;
  static int init=0;
  unsigned long pix;
  u_char *vimage;
  XImage *image;

  gray =0;
  points = width * height;
  vimage = (u_char *)malloc(points);
  if(vimage == NULL) goto alcer;

  vb = -1;
  for(i=0; i< points; i++ ){
    vd = (int)*(vdisp+i);
    if(gray != 1){
      *(vimage+i) =(u_char)color[vd].pixel;
    } else {
      *(vimage+i) =(u_char)vd;
    }
#define DEBUG False
#if DEBUG
    if(i/width - ((i/width)/18)*18 == 0){
      v = (int)*(vimage+i); vimg = v; vdsp = (int)*(vdisp+i);
      pix =color[*(vdisp+i)].pixel;
      if(v !=vb) printf("i,vdsp,pix,vimg in put_image= %d %d %ld %d\n"
                        ,i,vdsp,pix,vimg);
      vb = v;}
#endif
#if DEBUG
    if(i/10 ==0) printf("\n");
    if(i/200 == 0) printf("\n i = %d\n",i);
       printf(" %d",*(vimage+i));
#endif
  }

  image =XCreateImage(disp,vis,depth,ZPixmap,0,
                      vimage,width,height,
                      depth,width);
  if(image == NULL){
    printf("XCreateImage failed in put_image\n");
    return NULL;
  }
  return image;

alcer:
  printf("alloc failed in put_image\n");
  return NULL;
}

/* ---------- dith_data ---------- */
/* ディザ方式でディスプレイするためのデータ生成 */
/* color in vd is supposed 24bit (8 bit each) */
/* 4 points are used to display 1 point to make 4 variations */
/* cf.
 normal display:
 1 point of 24 bit color
      ↓
 1 point of 256 color (each r,g,b is 0-red_max etc. variations

this program:
 1 point of 24 bit color
      ↓
 4 point of 256 color (each r,g,b is 0-red_max etc. variations

   col % 5

    1  3
    4  2                   */
/*--------------------------*/
/*                             last modification     2000.08.29  */
u_char *dith_data(u_char *vdata, u_char **vdp, int width, int height
                  , XStandardColormap *scmap, struct rasin *rasin){
/*                  , XStandardColormap *scmap ){ 2000.08.29 */
  int x, y, l, points, col, maxf[3], mult[3], kk, k, cbase, cout, vdot
    , xt, yt;
  int vdmax = 255;
  int dx[4]={ 0, 1, 1, 0}
  , dy[4]={ 0, 1, 0, 1};
  u_char *vdo, *vdop[MAX_HEIGHT];
  unsigned long r, g, b;


  points = width * height;
  vdo =(u_char *)malloc(points);
  for(y=0; y< height; y++)
    vdop[y] = vdo + width*y;
  maxf[0] = scmap->red_max; maxf[1] = scmap->green_max;
  maxf[2] = scmap->blue_max; mult[0] = scmap->red_mult;
  mult[1] = scmap->green_mult; mult[2] = scmap->blue_mult;

  for(y=0; y < height-1; y +=2){
    for(x=0; x < width-1; x +=2){
      for(k =0; k < 4; k++)
        f_xy(vdop, x + dx[k], y + dy[k]) = scmap->base_pixel;
/*            {*(vdo + (y+dy[k])*width +(x+dx[k])) = (u_char)scmap->base_pixel;}
*/
      for(l=0; l < 3; l++){ /* l: 0-2 means r,g,b */
        col = f_xyc2(vdp,x,y,l);
        /* col: 0-255 mapped to 0-(maxf) * 4) */
        col = col * (4 * maxf[l] + 1)/(vdmax + 1);

        cbase = (col-1)/4; kk = (col-1) % 4 +1;
#define DEBUG False
#if DEBUG
        if(col != 0 && x % 20 == 0 && y % 20 == 0){
          printf(
"--- x, y,l,col,cbase,kk,maxf,mult in dith_data = %d %d %d %d %d %d %d %d\n"
                 ,x,y,l,col,cbase,kk,maxf,mult);}
#endif

        for(k = 1; k <= 4; k++){
          cout = cbase;
          if(kk > 0 && k <= kk) cout++;
          f_xy(vdop, x + dx[k-1], y + dy[k-1]) += cout * mult[l];
#define DEBUG False
#if DEBUG
          vdot = *(vdo + (y+dy[k-1])*width+(x+dx[k-1]) );
          xt = x + dx[k-1]; yt = y + dy[k-1];
          if((r != 0 || g != 0 || b !=0) && x % 20 == 0 && y % 20 == 0){
            printf("k,xt,yt,cout,vdot in dith_data = %d %d %d %d %d\n"
                   ,k,xt,yt,cout,vdot);}
          if(y % 10 == 0 && x == 100){
            printf("Hit Return Key to continue\n");
            getchar();
          }
#endif
        } /* loop k end */
      } /* loop l end */
    } /* loop x end */
  } /* loop y end */
  return vdo;
} /* end of dith_disp */


/* ---------- homo_hist ---------- */
/*                             last modification     2000.08.30  */
XStandardColormap *homo_hist(u_char **vdp, int width, int height
, int *pixs, struct Display_color *dspcol, u_char levav[][3]
, u_char ctable[][3], struct rasin *rasin){
/*, u_char ctable[][3]{ 2000.08.30 */
  int l, maxf[3], vdmax=255, i, sect, sects;
  unsigned long r, g, b; XColor *color,color2;
  int scn = 0;
  static XStandardColormap *scmap;
  static XStandardColormap scmapa[3] =
    {{NULL, 5, 36, 5, 6, 5, 1, 0}
    ,{NULL, 7, 32, 7, 4, 3, 1, 0}
    ,{NULL, 6, 35, 6, 5, 4, 1, 0}};
  u_char levav2[20][3], ctable2[256][3]; int levavt, ctablet;

  scmap = scmapa + scn;
  dspcol->scmap = scmap;
  maxf[0] = scmap->red_max  ; maxf[1] = scmap->green_max ;
  maxf[2] = scmap->blue_max ;
  for(l = 0; l < 3; l++){ /* l: 0-2 means r,g,b */
    histc(vdp, width, height, l, maxf, levav, ctable, rasin);
/*      histc(vdp, width, height, l, maxf, levav, ctable); 2000.08.30 */
   }
#define DEBUG False
#if DEBUG
  prin_levavs(levav,ctable);
  for(l = 0; l < 3; l++){
    sects = maxf[l]+1;
    for(sect = 0; sect < 20; sect++){
      levav2[sect][l] = 0; levavt =(int)levav2[sect][l];
      /* 0-maxf+1 mapped to 0-256 */
      if(sect < sects)
        levav2[sect][l] = (u_char)((sect * 256)/(maxf[l]+1)) ;
      levavt =(int)levav2[sect][l];
    }
    for(i = 0; i <= 255; i++){
      /* 0-256 mapped to 0-maxf+1 */
      ctable2[i][l] = (u_char)(i * (maxf[l] + 1)/256);}
    ctablet = ctable2[i][l];
  }
  prin_levavs(levav2,ctable2);
#endif
  *pixs = ((scmap->red_max)  + 1) * ((scmap->green_max) + 1)
    * ((scmap->blue_max) + 1);
  color = (XColor *)malloc(*pixs * sizeof(XColor));
  if(color == NULL) goto alcer;
  dspcol->color = color; dspcol->pixs = *pixs;
  i = 0;
  for(r =0; r <= scmap->red_max; r++){
    for(g =0; g <= scmap->green_max; g++){
      for(b =0; b <= scmap->blue_max; b++){
        color[i].red   = levav[r][0] * 65536/(vdmax+1);
        /* levav: 0-256 mapped to 0-65536 */
        /*            color[i].red   = (2 * levav[r][0] * 65535 + vdmax)/(2 * vd
max); */
        color[i].green = levav[g][1] * 65536/(vdmax+1);
        color[i].blue  = levav[b][2] * 65536/(vdmax+1);
        color[i].pixel = scmap->base_pixel + r * scmap->red_mult
          + g * scmap->green_mult + b * scmap->blue_mult;
        color[i].flags = DoRed | DoGreen | DoBlue;
        i++;
#define DEBUG False
#if DEBUG
        color2 = color[i];
        printf("i,r,g,b,pix in set_cmap= %d %d %d %d %d\n"
               ,i,color2.red,color2.green,color2.blue,color2.pixel);
#endif
      }
    }
  }
  return scmap;
alcer:
  printf("allocation error in homo_hist\n");
  return (XStandardColormap *)NULL;
}


/* ---------- prin_levavs ---------- */
/*                             last modification     1999.11.11  */
int prin_levavs(u_char levav[][3], u_char ctable[][3]){
  int l,i;
  printf("--- levav in homo_hist ---\n");
  for(l = 0; l < 3;  l++){
    for(i = 0; i < 20; i++){
      printf("%d  ",levav[i][l]);
    } printf("\n\n"); }
  printf("\n\n");
  printf("--- ctable in homo_hist ---\n");
  for(l = 0; l < 3;   l++){
    for(i = 0; i < 256; i++){
      printf("%d  ",ctable[i][l]);
      if(i % 20 == 19) printf("\n");
    }   printf("\n\n");}
  printf("\n");
}


/* ---------- histc ---------- */
/*                             last modification     2000.08.30  */
int histc(u_char **vdp, int width, int height, int l, int *maxf
, u_char levav[][3], u_char ctable[][3], struct rasin *rasin){ /* levav[sects][3
], ctable[vdmax+1][3]; */
/*, u_char levav[][3], u_char ctable[][3]){ /* 2000.08.30 */
   int sect, sects, lev, levb, ptsum, ptsums, ptsum_trg, points
     , vdmax = 255, x ,y;
   long levsums;

   points = width * height;
   sects = maxf[l] + 1;
   lev = 0; /* 画像輝度値の対象レベルを0から増加させる */
   ptsum = 0; /* 当該sectまでの累積度数 */

   for(sect =0; sect < sects; sect++){ /* 各区間の左端をsectで代表する */
     ptsum_trg = points * (sect +1)/ (4 *sects); /* 当該sectまでの累積度数目標値
 */
/*      ptsum_trg = (2 * points * (sect +1) + sects)/(2 * sects);*/
/*      if(ptsum >= ptsum_prg){*/  /* sh080400.rasのように途中で終っているデータ
への対応 */
     ptsums = 0; levsums = 0;

/* 累積度数が当該sectまでの目標値を上回るまでlevを増加 */
     while(ptsum < ptsum_trg && lev <= vdmax){
       ctable[lev][l] = sect; /* r,g,bのレベルをコード番号に対応させる表 */
       for(y = 0; y < height; y += 2){
         for(x = 0; x < width; x += 2){
           if(f_xyc2(vdp, x, y, l) == lev)
             {ptsum++; ptsums++; levsums += lev;}
         } /* end of x loop */
       } /* end of y loop */
       levb = lev; lev++;
     } /* end of lev loop */
     if(ptsums !=0){
       levav[sect][l] = (2 * levsums + ptsums)/(2 * ptsums);
     } else {
       levav[sect][l] = levb;
       /* sectがsectsに達する前にlevが255になった場合は、最後のlevを使う */
     }
   } /* end of sect loop */
 }


/* ---------- data_to_dsph ---------- */
/* ダイレクトカラーデータ向けにvdataからvdispデータを生成 */
/*                             last modification     2000.08.30  */
u_char *data_to_dsph(u_char *vdata, int points, XStandardColormap *scmap
, int pixs, u_char levav[][3], u_char ctable[][3], struct rasin *rasin){
/*, int pixs, u_char levav[][3], u_char ctable[][3]){ 2000.08.30 */
  u_char *vdisp;
  int i, j, l, ri, gi, bi, d, dmin, jmin[3];
  int vdmax = 255, vdm2, in[3];
  unsigned long r, g, b, r1, g1, b1, r2, g2, b2, pix;

  vdisp = (u_char *)malloc(points);
  if(vdisp == NULL) goto alcer;
  vdm2 = vdmax * 2;
  for(i = 0; i < points; i++){
    ri = vdata[rasin->pix_span*i+rasin->pix_offset+rasin->r_offset];
    gi = vdata[rasin->pix_span*i+rasin->pix_offset+rasin->g_offset];
    bi = vdata[rasin->pix_span*i+rasin->pix_offset+rasin->b_offset];
/*      ri = vdata[3*i+2]; gi = vdata[3*i+1]; bi = vdata[3*i  ]; 2000.08.30 */
    r1  = ctable[ri][0]; g1 = ctable[gi][1]; b1 = ctable[bi][2];
/*      in[0] = ri; in[1] = gi; in[2] = bi;
        for(l = 0; l < 3; l++){
        dmin = 1000000;
        for(j = 0; j < 8; j++){
        d = (in[l] - levav[j][l]) * (in[l] - levav[j][l]);
        if(d < dmin){
        dmin = d; jmin[l] = j;
        }
        }
        }
      r2 = jmin[0]; g2 = jmin[1]; b2 = jmin[2];*/
    r = r1; g = g1; b = g1;
    pix = scmap->base_pixel + r*scmap->red_mult + g*scmap->green_mult
      + b*scmap->blue_mult;
    if(pix > pixs-1) pix = pixs-1;
    *(vdisp+i) = (u_char)pix;
#define DEBUG False
#if DEBUG
    if(r == 5 && g == 5 && b == 5){
      if(!(ri==0 && gi==0 && bi==0))
        printf("i,r,g,b,pix in data_to_dsph = %d %d %d %d %d\n",i,r,g,b,pix);}
#endif
  }
  return vdisp;
alcer:
  printf("alloc failed in mk_nrmcmp\n");
  return NULL;
}


/* ---------- make_bwn ---------- */
void
make_bwn(u_char **datap, u_char **bwp, int width, int height, int defon
         , int defoff, int th)
{
  int x, y;

  for(y = 0; y < height; y++){
    for(x = 0; x < width; x++){
      if((int)f_xy(datap, x, y) > th) {
        f_xy(bwp, x, y) = defon;}
      else{
        f_xy(bwp, x, y) = defoff;
      }
    }
  }
}




戻る