⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.c

📁 《Linux程序设计权威指南》源代码
💻 C
字号:
	/* File: image.c */	#include <X11/Xlib.h>	#include <X11/Xutil.h>	#include <X11/Xos.h>	#include <X11/Xatom.h>	#include <stdio.h>	#define COLORS  8	#define IMAGE_WIDTH   320	#define IMAGE_HEIGHT   200	#define MAXDEPTH 200	typedef struct {		double real, imag;	} complex;	static void complexInit(complex *z, double r, double i)	{		z->real = r; z->imag = i;		return;	}	static void complexAdd(complex *z, complex u)	{		z->real += u.real;		z->imag += u.imag;	}	static void complexSub(complex *z, complex u)	{		z->real -= u.real;		z->imag -= u.imag;	}	static void complexMult(complex *z, complex u)	{		double tmp;		tmp = z->real*u.real - z->imag*u.imag;		z->imag = z->real*u.imag + z->imag*u.real;		z->real = tmp;	}	static double complexReal(complex *z)	{		return z->real;	}	static double complexImag(complex *z)	{		return z->imag;	}	static void complexPrint(complex *z)	{		printf("%.2g+%.2gi", complexReal(z), complexImag(z));	}	static double complexAbsSquare(complex *z)	{		return z->real*z->real+ z->imag*z->imag;	}	static int julia(complex z, complex c)	{		int n;		/* f(z) := z*z - c */		for(n=0; n<MAXDEPTH; n++){			complexMult(&z, z);			complexSub(&z, c);			/* if(complexAbs(&z)>2.0) */			if(complexAbsSquare(&z)>4.0)				return n;		}		return 0;	}	void draw(Display *display, Window win, GC gc,		XImage *img, XColor rgb[], int colors)	{		complex initial, point;		int i, j;		int w = IMAGE_WIDTH, h = IMAGE_HEIGHT;		complexInit(&initial, 0.0, 0.0);		printf("Rendering [%3d,%3d] fractal, please wait.\n", w, h);		for(j=0; j<h; j++)		for(i=0; i<w; i++) {			int c;			complexInit(&point, 2.5*(i-w/3)/w, 2.1*(j-h/2)/h);			c = julia(initial, point);			if(i%25==0) {				printf("[%4d,%4d] = %4d\r", i, j, c);			}			img->f.put_pixel(img, i, j, rgb[c%colors].pixel);		}	}	void reverse_image(XImage *img)	{		unsigned long pixelvalue1, pixelvalue2;		int y;		int left_x, right_x;		for (left_x=0 ; left_x<IMAGE_WIDTH/2 ; left_x++){			for (y=0 ; y<IMAGE_HEIGHT ; y++){                		pixelvalue1 = XGetPixel(img, left_x, y);				right_x = IMAGE_WIDTH - left_x;				if (left_x != right_x){					pixelvalue2 = XGetPixel(img,right_x, y);					XPutPixel(img, left_x, y, pixelvalue2);				}				XPutPixel(img, right_x, y, pixelvalue1);			}		}	}	int main(int argc, char **argv)	{		int i;		Display *display;		int screen_num;		Window win;			//窗口ID		unsigned int width, height;	//窗口尺寸		unsigned int border_width = 4;	//边界空白		unsigned int display_width, display_height;//屏幕尺寸		int count;		XEvent report;		char *display_name = NULL;		GC gc;		//颜色表		Colormap default_cmap;		XColor rgb[COLORS];		//图像		XImage *img, *cimg = NULL;	//图像和所拷贝的图像		XVisualInfo vis, *vlist;	//Visual 信息		Visual *visual;			//Visual		int depth;		int match;		int temp;		int w, h;		unsigned char *bit_data, *bitp, *datap;		unsigned char *tmpdata;		int bytes_per_line;		//每行字节数		// 和X 服务器连接		if ( (display=XOpenDisplay(display_name)) == NULL )		{			printf("Cannot connect to X server %s\n", 					XDisplayName(display_name));			exit(-1);		}		//获得缺省的 screen_num		screen_num = DefaultScreen(display);		//建立GC		gc = DefaultGC(display, screen_num);		//获得颜色深度		depth = DefaultDepthOfScreen(DefaultScreenOfDisplay(display));		//获得屏幕的宽度和高度		display_width = DisplayWidth(display, screen_num);		display_height = DisplayHeight(display, screen_num);		//获取缺省的颜色表		default_cmap = DefaultColormap(display, screen_num);		//获得Visual信息		vis.screen = screen_num;		vlist = XGetVisualInfo(display, 			VisualScreenMask, 		//掩码			&vis, 				//返回visual			&match);			//所符合的Visual结构		if(!vlist){			printf("No matched visuals\n");			exit(1);		}		vis = vlist[0];		XFree(vlist);		//判断颜色表大小是否合适		if(vis.colormap_size<COLORS){			printf("Colormap is too small.\n");			exit(1);		}		//设置灰度级颜色表		for(i=0; i<COLORS; i++){			rgb[i].red = 65535 * (1.0-1.0*i/COLORS);			rgb[i].green = 65535 * (1.0-1.0*i/COLORS);;			rgb[i].blue = 65535 * (1.0*i/COLORS);;			rgb[i].flags = DoRed|DoGreen|DoBlue;		}		//奇数class, 重定义颜色		if(vis.class%2==1){			unsigned long color[COLORS];			//分配颜色单元			if(XAllocColorCells(display, default_cmap, 1, NULL, 0,				color, COLORS)==0){				printf("Cannot allocate enough colors cells.\n");				exit(1);			}			//修改颜色单元			for(i=0; i<COLORS; i++) rgb[i].pixel = color[i];			XStoreColors(display, default_cmap, rgb, COLORS);		} else if(vis.class == TrueColor){			//分配颜色			for(i=0; i<COLORS; i++)				XAllocColor(display, default_cmap, rgb + i);		} else {			printf("No content with visual class %d.\n",				vis.class);			exit(1);		}		switch(depth){		case 6:		case 8:			img = XCreateImage(display,				vis.visual,				depth,				ZPixmap,				0,				(char *)malloc(IMAGE_WIDTH*IMAGE_HEIGHT),				IMAGE_WIDTH, IMAGE_HEIGHT,				8,				IMAGE_WIDTH);			break;		case 16:                	bit_data = (unsigned char *)malloc(IMAGE_WIDTH * IMAGE_HEIGHT * 2);			img = XCreateImage(display, 				vis.visual, 				vis.depth, 				ZPixmap, 				0, 				bit_data, 				IMAGE_WIDTH, IMAGE_HEIGHT,				16, 				0);			break;		case 24:			bit_data = (unsigned char *)malloc(IMAGE_WIDTH * IMAGE_HEIGHT * 4);			img = XCreateImage(display,				vis.visual,				depth,				ZPixmap,				0,				(char *)bit_data,				IMAGE_WIDTH, IMAGE_HEIGHT, 				32, 				0);			break;		default:			exit(1);		}		//指定所建立窗口的宽度和高度		//width = display_width/2;		//height = display_height/2;		width = 600;		height = 400;		//数据生成		draw(display, win, gc, img, rgb, COLORS);		//建立窗口		win = XCreateSimpleWindow(display, 	//display			RootWindow(display,screen_num), //父窗口			0, 0, width, height, 		//位置和大小			border_width, 			//边界宽度			BlackPixel(display,screen_num), //前景色			WhitePixel(display,screen_num));//背景色			//选择窗口感兴趣的事件掩码		XSelectInput(display, win, 			ExposureMask | KeyPressMask | 			ButtonPressMask | StructureNotifyMask);		//显示窗口		XMapWindow(display, win);		//把图像放到窗口上		XPutImage(display, win, gc, img, 0, 0, 0, 0,			IMAGE_WIDTH,IMAGE_HEIGHT);		//取得图像		cimg = XGetImage(display, win, 0, 0, 			IMAGE_WIDTH, IMAGE_HEIGHT, AllPlanes, ZPixmap);		reverse_image(cimg);		//进入事件循环		while (1)  {			//取得队列中的事件			XNextEvent(display, &report);			switch  (report.type) {			//曝光事件, 窗口应重绘			case Expose:				//取得最后一个曝光事件				if (report.xexpose.count != 0) break;				//画图像				XPutImage(display, win, gc, img, 					0, 0, 0, 0, IMAGE_WIDTH,IMAGE_HEIGHT);				//拷贝图像				XPutImage(display, win, gc, cimg, 					0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 					IMAGE_WIDTH, IMAGE_HEIGHT);				break;			//窗口尺寸改变, 重新取得窗口的宽度和高度			case ConfigureNotify:				width = report.xconfigure.width;				height = report.xconfigure.height;				break;			//鼠标点击或有按键, 释放资源则退出			case ButtonPress:			case KeyPress:				XDestroyImage(img);				XDestroyImage(cimg);				XFreeGC(display, gc);				//XCloseDisplay(display);				exit(1);			default:								break;			}		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -