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