www.pudn.com > match-v3.3.src.rar > image.cpp


/* image.cpp */ 
/* Vladimir Kolmogorov (vnk@cs.cornell.edu), 2001. */ 
 
#include  
#include "image.h" 
 
const int ONE = 1; 
const int SWAP_BYTES = (((char *)(&ONE))[0] == 0) ? 1 : 0; 
 
/************************************************************/ 
/************************************************************/ 
/************************************************************/ 
 
void * imNew(ImageType type, int xsize, int ysize) 
{ 
	void *ptr; 
	GeneralImage im; 
	int data_size; 
	int y; 
 
	if (xsize<=0 || ysize<=0) return NULL; 
 
	switch (type) 
	{ 
		case IMAGE_BINARY: data_size = sizeof(unsigned char);    break; 
		case IMAGE_GRAY:   data_size = sizeof(unsigned char);    break; 
		case IMAGE_SHORT:  data_size = sizeof(short);            break; 
		case IMAGE_RGB:    data_size = sizeof(unsigned char[3]); break; 
		case IMAGE_LONG:   data_size = sizeof(long);             break; 
		case IMAGE_PTR:    data_size = sizeof(void *);           break; 
		case IMAGE_FLOAT:  data_size = sizeof(float);            break; 
		case IMAGE_DOUBLE: data_size = sizeof(double);           break; 
		default: return NULL; 
	} 
 
	ptr = malloc(sizeof(ImageHeader) + ysize*sizeof(void*)); 
	if (!ptr) return NULL; 
	im = (GeneralImage) ((char*)ptr + sizeof(ImageHeader)); 
 
	imHeader(im) -> type      = type; 
	imHeader(im) -> data_size = data_size; 
	imHeader(im) -> xsize     = xsize; 
	imHeader(im) -> ysize     = ysize; 
 
	im->data = (void *) malloc(xsize*ysize*data_size); 
	for (y=1; ydata = ((char*)(im->data)) + xsize*y*data_size; 
 
	return im; 
} 
 
/************************************************************/ 
/************************************************************/ 
/************************************************************/ 
 
inline int is_digit(unsigned char c) { return (c>='0' && c<='9'); } 
 
void SwapBytes(GeneralImage im) 
{ 
	if (SWAP_BYTES) 
	{ 
		ImageType type = imHeader(im) -> type; 
 
		if (type==IMAGE_SHORT || type==IMAGE_LONG || type==IMAGE_FLOAT || type==IMAGE_DOUBLE) 
		{ 
			char *ptr, c; 
			int i, k; 
 
			int size = (imHeader(im) -> xsize) * (imHeader(im) -> ysize); 
			int data_size = imHeader(im) -> data_size; 
 
			ptr = (char *) (im->data); 
			for (i=0; i= num_max) { fclose(fp); return NULL; } 
				num[num_read] = c - '0'; 
				for (; c=LINE[i+1]; i++) 
				{ 
					if (!is_digit(c)) break; 
					num[num_read] = 10*num[num_read] + c - '0'; 
				} 
				num_read ++; 
			} 
		} 
 
		if (num_read >= num_max) break; 
	} 
 
	if (num_read != num_max) { fclose(fp); return NULL; } 
 
	xsize = num[0]; 
	ysize = num[1]; 
	im = (GeneralImage) imNew(type, xsize, ysize); 
	if (!im) { fclose(fp); return NULL; } 
	data_size = imHeader(im) -> data_size; 
 
	if (is_text) 
	{ 
		num_read = 0; 
		if (type == IMAGE_RGB) num_max = 3*xsize*ysize; 
		else                   num_max = xsize*ysize; 
 
		while (fgets((char *)LINE, sizeof(LINE), fp)) 
		{ 
			for (i=0; c=LINE[i]; i++) 
			{ 
				if (c == '#') break; 
				if (is_digit(c)) 
				{ 
					int tmp; 
					if (num_read >= num_max) { imFree(im); fclose(fp); return NULL; } 
					tmp = c - '0'; 
					for (; c=LINE[i+1]; i++) 
					{ 
						if (!is_digit(c)) break; 
						tmp = 10*tmp + c - '0'; 
					} 
					if      (type == IMAGE_BINARY) imRef((BinaryImage)im, num_read, 0) = tmp; 
					else if (type == IMAGE_GRAY)   imRef((GrayImage)im,   num_read, 0) = tmp; 
					else 
					{ 
						switch (num_read % 3) 
						{ 
							case 0: imRef((RGBImage)im, num_read/3, 0).r = tmp; break; 
							case 1: imRef((RGBImage)im, num_read/3, 0).g = tmp; break; 
							case 2: imRef((RGBImage)im, num_read/3, 0).b = tmp; break; 
						} 
					} 
					num_read ++; 
				} 
			} 
		} 
 
		if (num_read != num_max) { imFree(im); fclose(fp); return NULL; } 
	} 
	else 
	{ 
		if (type == IMAGE_BINARY) 
		{ 
			int s = (xsize*ysize+7)/8; 
			unsigned char *b = (unsigned char *) malloc(s); 
			if (!b) { imFree(im); fclose(fp); return NULL; } 
			if (fread(b, 1, s, fp) != (size_t)s) { free(b); imFree(im); fclose(fp); return NULL; } 
			for (i=0; idata[i] = ( b[i/8] & (1<<(7-(i%8))) ) ? 1 : 0; 
			} 
			free(b); 
		} 
		else 
		{ 
			if (fread(im->data, data_size, xsize*ysize, fp) != (size_t)(xsize*ysize)) { imFree(im); fclose(fp); return NULL; } 
		} 
		SwapBytes(im); 
	} 
 
	fclose(fp); 
 
	return im; 
} 
 
/************************************************************/ 
/************************************************************/ 
/************************************************************/ 
 
int imSave(void *im, char *filename) 
{ 
	int i; 
	FILE *fp; 
	int im_max = 0; 
	ImageType type = imHeader(im) -> type; 
	int xsize = imHeader(im) -> xsize, ysize = imHeader(im) -> ysize; 
	int data_size = imHeader(im) -> data_size; 
 
	fp = fopen(filename, "wb"); 
	if (!fp) return -1; 
 
	switch (type) 
	{ 
		case IMAGE_BINARY: 
			fprintf(fp, "P4\n%d %d\n", xsize, ysize); 
			break; 
		case IMAGE_GRAY: 
			for (i=0; idata[i]) im_max = ((GrayImage)im)->data[i]; 
			fprintf(fp, "P5\n%d %d\n%d\n", xsize, ysize, im_max); 
			break; 
		case IMAGE_RGB: 
			for (i=0; idata[i].r) im_max = ((RGBImage)im)->data[i].r; 
				if (im_max < ((RGBImage)im)->data[i].g) im_max = ((RGBImage)im)->data[i].g; 
				if (im_max < ((RGBImage)im)->data[i].b) im_max = ((RGBImage)im)->data[i].b; 
			} 
			fprintf(fp, "P6\n%d %d\n%d\n", xsize, ysize, im_max); 
			break; 
		case IMAGE_SHORT: 
			fprintf(fp, "Q4\n%d %d\n", xsize, ysize); 
			break; 
		case IMAGE_LONG: 
			fprintf(fp, "Q3\n%d %d\n", xsize, ysize); 
			break; 
		case IMAGE_FLOAT: 
			fprintf(fp, "Q1\n%d %d\n", xsize, ysize); 
			break; 
		case IMAGE_DOUBLE: 
			fprintf(fp, "Q2\n%d %d\n", xsize, ysize); 
			break; 
		default: 
			fclose(fp); 
			return -1; 
	} 
 
	if (type == IMAGE_BINARY) 
	{ 
		int s = (xsize*ysize+7)/8; 
		unsigned char *b = (unsigned char *) malloc(s); 
		if (!b) { fclose(fp); return -1; } 
		for (i=0; idata[i]) 
				b[i/8] ^= (1<<(7-(i%8))); 
		} 
		i = fwrite(b, 1, s, fp); 
		free(b); 
		if (i != s) { fclose(fp); return -1; } 
	} 
	else 
	{ 
		SwapBytes((GeneralImage)im); 
		i = fwrite(((GeneralImage)im)->data, data_size, xsize*ysize, fp); 
		SwapBytes((GeneralImage)im); 
		if (i != xsize*ysize) { fclose(fp); return -1; } 
	} 
 
	fclose(fp); 
	return 0; 
}