/* --- sampled.c ver1.0 */
/* originally coded by M. Hirasawa & T. Hasegawa 2001/04/13 (named sample.c) */
/* revised by M. Oshima for size flexibility of image data file
and to process Expose event (named samplen.c) */
/* revised by M. Oshima to give flexibility on input file and display
(named sampled.c) */
/* 1st release 2001.07.23 */
/* --- last modification 2001.07.23 */
/* usage example sampled 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 (chimf is helpful ) */
/* if you adopt *(data + y*width + x) instead to data[y][x],
no need to define XMAX and YMAX */
/*#define XMAX 720*/ /* for dome.ras */
/*#define YMAX 486*/
static Window root, win1, win2, wins[2];
static Display *disp;
static Visual *vis;
static Colormap cmap;
static GC gc;
static int deptho;
static int width, height, depthi, length; /* 2001.0
7.11 */
static Status grayo;
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";
/*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 *, XColor *colt, Status *grayi);
void set_colt(u_char *colbuf, int maplength, int maptype, XColor *colt);
int set_lud(unsigned short lutd[][256], XColor *colt, int depthi, int deptho
, Status grayi);
XImage *mk_image(u_char *data, int width, int height, int depthi, int deptho
, unsigned short lutd[][256], Status grayi, int imode, XColor *colt);
Window make_win(char *);
void graphic_intialize(void);
void evntloop(XImage *images[], Window wins[]);
u_char *decode_vdata(u_char *vdata, int width, int height, int length);
u_char
*bm_to_gray(u_char *vdataf, int width, int height, int length, int black
, int white);
int main(int argc, char **argv)
{
int i, j, pad;
u_char *input_data, *output_data;
char name[50];
XImage *image1, *image2, *images[2];
XColor colt[256];
unsigned short lutd[3][256];
int imode;
Status grayi;
if( argc != 2 ){
printf("Usage: %s [data_name]\n", argv[0]);
exit(1);
}
name[0] = '\0';
strcat(name, argv[1]);
/* width, height & depthi are set in get_image */
input_data = get_image(name, colt, &grayi);
graphic_intialize();
imode = set_lud(lutd ,colt, depthi, deptho, grayi);
win1 = make_win(names1);
image1 = mk_image(input_data, width, height, depthi, deptho, lutd, grayi
, imode, colt);
XPutImage(disp, win1, gc, image1, 0, 0, 0, 0, width, height);
XMapWindow(disp, win1);
XFlush(disp);
puts("Hit [Enter]!");
getchar();
pad = width % 2;
output_data = (u_char *)malloc((width + pad) * height * (depthi /8) * sizeof(u
_char));
/* -- start ------------------------------------------------------- */
user_prog2(input_data, output_data, width, height);
/* -- end ------------------------------------------------------- */
win2 = make_win(names2);
image2 = mk_image(output_data, width, height, depthi, deptho, lutd, grayi
, imode, colt);
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);
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, byte, bytel;
bytel = depthi/8;
for(y = 0; y < height; y++){
for(x = 0; x < width; x++){
for(byte = 0; byte < bytel; byte++, output_data++, input_data++){
*output_data = *input_data;
/* output_data[y][x] = input_data[y][x]; */
}
}
}
}
u_char
*get_image(char *name, XColor *colt, Status *grayi)
{
u_char *colbuf;
FILE *fpin;
u_char *vd;
int maptype, maplength;
fpin = fopen(name, "r");
if(fpin == NULL){
fprintf(stderr, "error: can't open %s!\n", name);
exit(1);
}
fread(&raster, sizeof(raster), 1, fpin);
width = raster.width; /* 2001.07.03 */
height = raster.height;
depthi = raster.depth;
length = raster.length;
maplength = raster.maplength;
maptype = raster.maptype;
*grayi = (depthi == 8 && maplength == 0)? True: False;
/* if colormap exists on rasterfile set lut */
if(maplength > 0){
colbuf = (u_char *)malloc(maplength * sizeof(char));
fread(colbuf, 1, maplength, fpin ); /* read colormap */
set_colt(colbuf, maplength, maptype, colt);
free(colbuf);
}
vd = (u_char*)malloc(length *sizeof(u_char)); /* 2001.07.11 */
fread( vd, 1, length, fpin );
fclose(fpin);
if(raster.type == 2) vd = decode_vdata(vd, width, height, length);
if(depthi ==1) {
vd = bm_to_gray( vd, width, height, length, 0, 255) ;
depthi = 8;
}
return vd;
}
void
set_colt(u_char *colbuf, int maplength, int maptype, XColor *colt)
/* if colormap exists on rasterfile set colt */
{
XColor t;
int i, pixs, r, g, b;
pixs = maplength/3;
for( i=0; i < pixs; i++ ) {
r = *(colbuf + i);
g = *(colbuf + pixs +i);
b = *(colbuf + 2*pixs +i);
t.red = r; t.green = g; t.blue = b; t.pixel = i;
colt[i] = t;
}
for( i=pixs; i < 256; i++ ) {
t.red = 0; t.green = 0; t.blue = 0; t.pixel = i;
colt[i] = t;
}
}
int
set_lud(unsigned short lutd[][256], XColor *colt, int depthi, int deptho
, Status grayi)
/* to set lut for depth= 8 display. variations per color supposed to be 6.
*/
/* --- set color pixel number on lut (coded by equal spaced number) */
/* lutd 0: for gray input, 1 for pseud color input , 2 full color input*/
/* 6 * 6 * 6 = 216 < 256 */
/* lut entry is coded by 6 * 6 * 6 for color*/
/* lut entry is coded by 256 for gray */
{
int imode, rc, gc, bc, dpc = 6, maxo, keisu;
unsigned short r, g, b, i;
unsigned long pixel, white, black;
XColor t;
Status status;
imode = 3; /* imode = 3 means direct both in and out */
if(depthi == 8 || deptho == 8) {
if(depthi == 16 || depthi == 24 || depthi == 32){
imode = 2;
} else {
imode = (grayi)? 0 : 1;
}
} else {
return imode;
}
white = WhitePixel(disp, 0);
t.pixel = white;
XQueryColor(disp, cmap, &t);
maxo = t.green + 1;
switch(imode){
case 0:
keisu = maxo /256;
for(i = 0; i < 256; i++){ /* for gray data input*/
t.red = (unsigned)i * keisu;
t.green = (unsigned)i * keisu;
t.blue = (unsigned)i * keisu;
XAllocColor(disp, cmap, &t);
lutd[0][i] = t.pixel;
}
break;
case 1:
keisu = maxo /256;
for(i = 0; i < 256; i++){ /* for pseud color input */
t.red = colt[i].red * keisu;
t.green = colt[i].green * keisu;
t.blue = colt[i].blue * keisu;
XAllocColor(disp, cmap, &t);
lutd[1][i] = t.pixel;
}
lutd[1][255] = white;
break;
case 2:
keisu = maxo / 6; /* for full color input */
for(rc=0; rc < dpc; rc++){ /* rc: red code 0-5 */
r = rc * keisu; t.red = r;
for(gc=0; gc < dpc; gc++){
g =gc * keisu; t.green = g;
for(bc=0; bc < dpc; bc++){
b = bc * keisu; t.blue = b;
status = XAllocColor(disp, cmap, &t);
if(status != True) goto err;
lutd[2][(rc * 6 + gc) * 6 + bc] = t.pixel;
}
}
}
/*white = WhitePixel(disp, 0);
black = BlackPixel(disp, 0);
lut[255] = white; lut[0] = black;*/
break;
default:
fprintf(stderr,"unexpected imode %d is received in set_lud\n",imode);
exit(1);
}
return imode;
err: fprintf(stderr,"alloc error in set_lud");
exit(1);
}
XImage
*mk_image(u_char *data, int width, int height, int depthi, int deptho
, unsigned short lutd[][256], Status grayi, int imode, XColor *colt)
/* make Ximage data for display from normalized (24 bit for color 8 bit for gray
) video data */
/* last modification 2001.07.20 */
{
int x, y, i, countx, pad;
u_char *data0;
static unsigned long r, g, b, rc, gc, bc, rcs[3], r_mul, g_mul, b_mul
, mask, pixel;
static char *pix_byte = (u_char *) &pixel;
static unsigned long masks[3]; static unsigned int shifts[3];
u_char *dto, *dto0;
XImage *image;
int vpci; /* variations per color for input */
int vpco, dci, dco, shift, byte, boffset;
int vpcis[5] = {0, 6, 32, 256, 256}; /* for 8,16,24,(32) depthi */
int vpcos[5] = {0, 6, 32, 256, 256}; /* for 8,16,24,(32) deptho */
static int vpcosc[3];
int muls[5][3] = /* 0-2 correspond to r-b */
{ 0, 0, 0 /* multiplier to compose pixel for display */
, 6*6, 6, 1 /* for 8 bit display */
, 32*32, 32, 1 /* for 16 bit */
,256*256, 256, 1 /* for 24 bit */
,256*256, 256, 1}; /* for 32 bit */
static int mulsc[3];
static int initted = 0;
dci = depthi / 8;
dco = deptho / 8;
/* --------- initial setting for display environment ---------- */
if(initted == 0) {
initted = 1;
for(i = 0; i < 3; i++){
mulsc[i] = muls[dco][i];
vpcosc[i] = vpcos[dco];
}
if(dco > 1){
masks[0] = vis->red_mask; masks[1] = vis->green_mask;
masks[2] = vis->blue_mask;
for(i = 0; i < 3; i++){
mask = masks[i]; shift = 0;
while( !((1 << shift) & mask) && shift < 32)
shift++;
shifts[i] = shift;
}
for(i = 0; i < 3; i++){
vpcosc[i] = (masks[i] >> shifts[i]) + 1;
}
mulsc[2] = 1; mulsc[1] = vpcosc[0]; mulsc[0] = vpcosc[1] * mulsc[1];
}
}
data0 = data;
dto = dto0 = (u_char *)malloc((unsigned)width*height*dco*sizeof(char));
if(dto == NULL)
exit(1);
if(dci == 1 && dco == 1){
for(y = 0; y < height; y++){
for(x = 0; x < width; x++, data ++, dto++){
pixel = lutd[imode][*data];
*dto = (u_char)pixel;
}
}
goto xcr;
}
vpci = vpcis[dci]; /* variations per color for input */
vpco = vpcos[dco]; /* variations per color for display */
if(dco == 1) { mulsc[0] = muls[dco][0]; mulsc[1] = muls[dco][1]; mulsc[2] = mu
ls[dco][2];}
pix_byte = (unsigned char*) &pixel;
pixel = lutd[imode][*data];
boffset = (dci == 4) ? 1 : 0;
for(y = 0; y < height; y++){
countx = 0; /* to treat pad */
for(x = 0; x < width; x++, data += dci, countx += dci){
/* ----------- to read data ------------ */
switch(dci){
case 1: /* here depthi =8, while deptho > 8 */
pixel = *data;
if(grayi){
pixel = lutd[imode][pixel];
} else {
r = colt[pixel].red; g = colt[pixel].green; b = colt[pixel].blue;
rc = (r * vpcosc[0])/256; gc = (g * vpcosc[1])/256; bc = (b * vpcosc[2
])/256;
pixel = rc * mulsc[0] + gc * mulsc[1] + bc * mulsc[2];
}
break;
case 3:
case 4:
b = *(data+boffset); g =*(data+1+boffset); r = *(data+2+boffset);
rc = (r * vpcosc[0])/vpci; gc = (g * vpcosc[1])/vpci; bc = (b * vpcosc[2
])/vpci;
pixel = rc * mulsc[0] + gc * mulsc[1] + bc * mulsc[2];
}
/* ----------- to write data for display ------------ */
if(dco == 1) { /* if display is 8 bit special treatment */
pixel = lutd[imode][pixel];
*dto = (u_char)pixel;
dto++;
continue;
} else {
for(byte =0; byte < dco; byte++, dto++)
*dto = pix_byte[4-dco+byte];
}
} /* x loop */
pad = countx % 2;
if(pad != 0 ) data += pad;
} /* y loop */
xcr:
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)
{
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(void)
{
unsigned short r, g, b;
XColor xc;
XStandardColormap *cmap2;
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);
XGetStandardColormap(disp, root, cmap2, XInternAtom(disp, "RGB_TEST_MAP", 0));
}
void evntloop(XImage *images[], Window wins[])
{
XEvent event;
Window win;
XImage *image;
int i, status;
status = 1;
while(status){
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,
width,height);
XFlush(disp);
break;
case ButtonPress :
fprintf(stderr, "ButtonPress event\n");
status =0;
break;
}
}
}
/* ---------- decode_vdata ---------- */
/* this is dedicated process for byte_encoded data */
/* coded by M. Oshima 1999.10.27 */
/* last modification 2001.07.21 */
/* data example: sh080400.ras */
u_char
*decode_vdata(u_char *vdata, int width, int height, int length){
int i, j, k, M, N, Nsum, pad;
u_char *vdata2;
pad = width % 2;
vdata2=(u_char *)malloc((width + pad) * height * 3);
if(vdata2 == NULL) goto alcer;
j = 0; Nsum =0;
for(i=0; i < length; i++){
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 != width * height * 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",
width * height *3, j);
return(u_char *)NULL;
}
/* ---------- bm_to_gray ---------- */
/* ビットマップデータ(depth=1)から8bビット濃淡画像形式のファイルを
作る */ /* vdatafからvdataiデータを生成 */
/* coded by M. Oshima 2001.07.20 */
/* last modification 2001.07.21 */
/* data example: clock0.ras */
u_char
*bm_to_gray(u_char *vdataf, int width, int height, int length, int black, int wh
ite)
{
u_char *vdatai, *vdatai0;
int l, x, y, i, byte, counthf, counthi, padi, bp, bmdata;
/* vdatai: data for internal (this is supposed to be normalized) */
padi = width % 2;
vdatai = vdatai0 = (u_char *)malloc((width + padi) * height * sizeof(char));
if(vdatai == NULL) goto alcer;
counthf =0; counthi = 0;
for(l =0; l < length; l++, vdataf++){
byte = *vdataf;
for(bp=7; bp >= 0; bp--, counthi++){
bmdata = (byte & (1 << bp)) >> bp; /* get bitmap data */
/* write w or b pixel on vdatai */
*vdatai++ = (bmdata == 1) ? white: black;
if(counthi == width-1){ /* end of horizontal line */
/* pad in vdataf is simply ignored */
padi = width % 2;
vdataf += padi; /* output pad (rounfed to 2 bytes) */
counthi =0;
break; /* go to next byte */
}
}
}
return vdatai0;
alcer:
fprintf(stderr, "alloc error in bm_to_gray\n");
exit(1);
}
}
戻る