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

📄 filter_rcg.c

📁 [Game.Programming].Academic - Graphics Gems (6 books source code)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *		Filtered Image Rescaling * *		  by Dale Schumacher * *//*	Additional changes by Ray Gardener, Daylon Graphics Ltd.	December 4, 1999	Summary:		- Horizontal filter contributions are calculated on the fly,		  as each column is mapped from src to dst image. This lets 		  us omit having to allocate a temporary full horizontal stretch 		  of the src image.		- If none of the src pixels within a sampling region differ, 		  then the output pixel is forced to equal (any of) the source pixel.		  This ensures that filters do not corrupt areas of constant color.		- Filter weight contribution results, after summing, are 		  rounded to the nearest pixel color value instead of 		  being casted to Pixel (usually an int or char). Otherwise, 		  artifacting occurs. 		- All memory allocations checked for failure; zoom() returns 		  error code. new_image() returns NULL if unable to allocate 		  pixel storage, even if Image struct can be allocated.		  Some assertions added.		- load_image(), save_image() take filenames, not file handles.		- TGA bitmap format available. If you want to add a filetype, 		  extend the gImageHandlers array, and factor in your load_image_xxx()		  and save_image_xxx() functions. Search for string 'add your' 		  to find appropriate code locations.		- The 'input' and 'output' command-line arguments do not have 		  to specify .bm files; any supported filetype is okay.		- Added implementation of getopt() if compiling under Windows.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <malloc.h>#include <math.h>#include "GraphicsGems.h"static char	_Program[] = "fzoom";static char	_Version[] = "0.30";static char	_Copyright[] = "Public Domain 1991 by Dale Schumacher. Mods by Ray Gardener";#ifndef EXIT_SUCCESS#define	EXIT_SUCCESS	(0)#define	EXIT_FAILURE	(1)#endif/* M_PI was not in gems header ?? */#ifndef M_PI	#define M_PI	 3.14159265359#endif#ifdef WIN32/* getopt() - Parses command line (argv) looking for switch chars 	Returns option flag char if option found.	Returns EOF if end of arglist or non-flag arg reached.	Returns 0 if option arg doesn't match any switch. 		rcg: No idea if this fully implements getopt()'s API;		just provided so main() would compile.	*/int optind;char *optarg;intgetopt(argc, argv, pszSwitches)int argc;char* argv[];char* pszSwitches;{	static int n = 1;	char* pszToken;	char*  arg = "- ";	char* szSwitches;		if(n >= argc || argv[n][0] != '-')	{		optind = n;		n = 1;		return EOF;	}	szSwitches = _strdup(pszSwitches);	if(szSwitches == NULL)		return EOF;	/* Compare argv[n] with acceptable switches */	pszToken = strtok(szSwitches, ":");	if(pszToken == NULL)	{		free(szSwitches);		return EOF;	}	while(pszToken)	{		if(strlen(argv[n]) > 1 && argv[n][0] == '-')		{			arg[1] = pszToken[0];			if(memcmp(arg, argv[n], 2) == 0)			{				optind = n++;				optarg = argv[n++];				free(szSwitches);				return arg[1];			}		}		pszToken = strtok(NULL, ":");	}	n++;	free(szSwitches);	return 0;}#endif // WIN32typedef	unsigned char	Pixel;/* Note: if you define Pixel to something bigger than char, 		you may need to add more support in bitmap file I/O functions.*/typedef struct{	int	xsize;		/* horizontal size of the image in Pixels */	int	ysize;		/* vertical size of the image in Pixels */	Pixel *	data;		/* pointer to first scanline of image */	int	span;		/* byte offset between two scanlines */} Image;#define	WHITE_PIXEL	(255)#define	BLACK_PIXEL	(0)/* *	generic image access and i/o support routines */static char *next_token(f)FILE *f;{	static char delim[] = " \t\r\n";	static char *t = NULL;	static char lnbuf[256];	char *p;	while(t == NULL) {			/* nothing in the buffer */		if(fgets(lnbuf, sizeof(lnbuf), f)) {	/* read a line */			if(p = strchr(lnbuf, '#')) {	/* clip any comment */				*p = '\0';			}			t = strtok(lnbuf, delim);	/* get first token */		} else {			return(NULL);		}	}	p = t;	t = strtok((char *)NULL, delim);		/* get next token */	return(p);}Pixelget_pixel(image, x, y)Image *image;int x, y;{	static Image *im = NULL;	static int yy = -1;	static Pixel *p = NULL;	if((x < 0) || (x >= image->xsize) || (y < 0) || (y >= image->ysize)) {		return(0);	}	if((im != image) || (yy != y)) {		im = image;		yy = y;		p = image->data + (y * image->span);	}	return(p[x]);}voidget_row(row, image, y)Pixel *row;Image *image;int y;{	if((y < 0) || (y >= image->ysize)) {		return;	}	memcpy(row,		image->data + (y * image->span),		(sizeof(Pixel) * image->xsize));}voidget_column(column, image, x)Pixel *column;Image *image;int x;{	int i, d;	Pixel *p;	if((x < 0) || (x >= image->xsize)) {		return;	}	d = image->span;	for(i = image->ysize, p = image->data + x; i-- > 0; p += d) {		*column++ = *p;	}}Pixelput_pixel(image, x, y, data)Image *image;int x, y;Pixel data;{	static Image *im = NULL;	static int yy = -1;	static Pixel *p = NULL;	if((x < 0) || (x >= image->xsize) || (y < 0) || (y >= image->ysize)) {		return(0);	}	if((im != image) || (yy != y)) {		im = image;		yy = y;		p = image->data + (y * image->span);	}	return(p[x] = data);}Image *new_image(xsize, ysize)	/* create a blank image */int xsize, ysize;{	Image *image;	ASSERT(xsize > 0 && ysize > 0);	if(image = (Image *)malloc(sizeof(Image)))	{		if(image->data = (Pixel *)calloc(ysize, xsize))		{			image->xsize = xsize;			image->ysize = ysize;			image->span = xsize;		}		else		{			free(image);			image = NULL;		}	}	return image;}voidfree_image(image)Image *image;{	ASSERT(image && image->data);	free(image->data);	free(image);}/*	fileextension()	Returns type of file based on its name.	Returns the empty string if filename has no extension */char*fileextension(f)char* f;{	/* Get a filename's extension string. */	int i;	for(i = strlen(f) - 1; i > 0; i--)	{		if(f[i] == '.')			return f + i + 1;	}	/* No extension. Return the end of the string, 	   which effectively returns a null string. */	return f + strlen(f);}/* add your filetype loaders and savers here *//* -- PXM bitmap support------------------------------------------------ */Image *load_image_bm(f)		/* read image from bm file */FILE *f;{	char *p;	int width, height;	Image *image;	if(((p = next_token(f)) && (strcmp(p, "Bm") == 0))	&& ((p = next_token(f)) && ((width = atoi(p)) > 0))	&& ((p = next_token(f)) && ((height = atoi(p)) > 0))	&& ((p = next_token(f)) && (strcmp(p, "8") == 0))	&& (image = new_image(width, height))	&& (fread(image->data, (size_t)width, (size_t)height, f) == (size_t)height)) {		return(image);		/* load successful */	} else {		return(NULL);		/* load failed */	}}intsave_image_bm(f, image)	/* write image to bm file */FILE *f;Image *image;{	fprintf(f, "Bm # PXM 8-bit greyscale image\x0A");	fprintf(f, "%d %d 8 # width height depth\x0A",		image->xsize, image->ysize);	if(fwrite(image->data, (size_t)image->xsize, (size_t)image->ysize, f) == (size_t)image->ysize) {		return(0);		/* save successful */	} else {		return(-1);		/* save failed */	}}/* -- TGA bitmap support------------------------------------------------ */typedef struct{	unsigned char	lsb, msb;} DoubleByte;#define INT_TO_DB(n, db)	{ (db).lsb = (unsigned char)((n) & 0xFF);\							  (db).msb = (unsigned char)((n) >> 8); }#define DB_TO_INT(db)		(((int)((db).msb) << 8) + (db).lsb)typedef struct{	unsigned char	IDfieldLen;	unsigned char	colorMapType;	unsigned char	imageType;	DoubleByte		ColorMapOrigin;	DoubleByte		ColorMapLen;	unsigned char	ColorMapEntrySize; /* no. of bits */	DoubleByte		Xorigin;	DoubleByte		Yorigin;	DoubleByte		Width;	DoubleByte		Height;	unsigned char	bpp;	unsigned char	descriptor;} TGAheader;intsave_image_tga(f, image)	/* save image to TGA file */FILE* f;Image* image;{	int x, y;	int n, j;	TGAheader	header;	boolean bOK = TRUE; /* assume success */	/* Grayscale images only. */	ASSERT(sizeof(Pixel) == 1);			/* Write header */	memset(&header, 0, sizeof(header));	header.colorMapType = 1;	header.imageType = 1;	INT_TO_DB(256, header.ColorMapLen);	header.ColorMapEntrySize = 24;	INT_TO_DB(image->xsize, header.Width);	INT_TO_DB(image->ysize, header.Height);	header.bpp = 8;	header.descriptor = 0x20; /* top down */	bOK = (fwrite(&header, sizeof(header), 1, f) == 1);  	/* Write palette. */	for(n = 0; n < 256 && bOK; n++)	{		for(j = 0; j < 3 && bOK; j++)			bOK = fputc(n, f) != EOF;	}			/* Write pixel index values. */	for(y = 0; y < image->ysize && bOK; y++)	{		for(x = 0; x < image->xsize && bOK; x++)			bOK = (EOF != fputc(get_pixel(image, x, y), f));	}	return bOK ? 0 : -1;} /* save_image_tga */Image *load_image_tga(f)		/* read image from TGA file */FILE *f;{	Image* image = NULL;	boolean bTopDown;	boolean bOK = FALSE;	TGAheader	header;	int	width, height, c, x, y, yy;	/* Grayscale images only. */	ASSERT(sizeof(Pixel) == 1);	if(fread(&header, sizeof(header), 1, f) == 1 && header.bpp == 8)	{		bTopDown = (header.descriptor & 0x20);		width = DB_TO_INT(header.Width);		height = DB_TO_INT(header.Height);		image = new_image(width, height);		if(image != NULL)		{			/* Skip palette */			bOK = 0 == fseek(f, DB_TO_INT(header.ColorMapLen) * header.ColorMapEntrySize/8, SEEK_CUR);			/* Read pixels */			for(y = 0; y < height && bOK; y++)			{				yy = bTopDown ? y : (height-1) - y;				for(x = 0; x < width && bOK; x++)				{					bOK = ((c = fgetc(f)) != EOF);					if(bOK)						put_pixel(image, x, yy, (Pixel)c);				}			}		}	}	if(!bOK && image != NULL)	{		free_image(image);		image = NULL;	}	return image;}/* -- End TGA bitmap support ------------------------------------------- *//*	ImageHandler stuff.	An ImageHandler stores an image file's extension, 	and pointers to functions that read and write the image format.*/typedef struct{	char* filetype;	Image* (*reader)();	int (*writer)();} ImageHandler;ImageHandler gImageHandlers[] ={	{ "bm", load_image_bm, save_image_bm },	{ "tga", load_image_tga, save_image_tga }	/* add your image handlers here */};/*	find_imagehandler()	Given a filename, return an image handler for it. 	Return NULL if no handler available.*/ImageHandler*find_imagehandler(f)char* f;{	int i;	for(i = 0; i < sizeof(gImageHandlers) / sizeof(gImageHandlers[0]); i++)	{		if(stricmp(gImageHandlers[i].filetype, fileextension(f)) == 0)			return &gImageHandlers[i];	}	return NULL;}/*	load_image()	Given a filename, hands off to appropriate image loader.	Returns pointer to loaded Image, NULL if it can't.*/Image *load_image(f)		/* read image from file */char *f;{	Image *image;	FILE* fp;	ImageHandler* handler;	ASSERT(f);		fp = fopen(f, "rb");	if(fp == NULL)		return NULL;	if(handler = find_imagehandler(f))		image = handler->reader(fp);	fclose(fp);	return image;}/*	save_image()	Given a filename and an Image, hands off to appropriate image saver.	Returns -1 on error, 0 on success.*/intsave_image(f, image)char *f;

⌨️ 快捷键说明

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