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

📄 imagbase.cpp

📁 《3D游戏引擎设计》的源码
💻 CPP
字号:
#include <fstream.h>
#include <string.h>
#include "imagbase.h"

// error handling
int mgcImage::verbose = 0;
unsigned mgcImage::error = 0;
const unsigned mgcImage::allocation_failed    = 0x00000001;
const unsigned mgcImage::zero_dimension       = 0x00000002;
const unsigned mgcImage::invalid_dimension    = 0x00000004;
const unsigned mgcImage::invalid_type         = 0x00000008;
const unsigned mgcImage::incompatible_types   = 0x00000010;
const unsigned mgcImage::load_failed          = 0x00000020;
const unsigned mgcImage::get_data_failed      = 0x00000040;
const unsigned mgcImage::save_failed          = 0x00000080;
const unsigned mgcImage::put_data_failed      = 0x00000100;
const char* mgcImage::message[9] = {
	"unable to allocate elements",
	"zero dimensions in argument list",
	"invalid dimensions in variable argument list",
	"invalid element type in constructor",
	"incompatible types in assignment",
	"load failed",
	"get data failed",
	"save failed",
	"put data failed"
};

// initialize elements to zero by default
int mgcImage::initialize_elements = 1;

//===========================================================================
void mgcImage::
Create (int _type)
{
	if ( !mgcElementDBM::Valid(_type) ) {
		Report(invalid_type);
		return;
	}

	type = _type;
	size = mgcElementDBM::MemorySize(type);
	int bytes = quantity*size;
	if ( bytes > 0 ) {
		if ( (data = new char[bytes]) == 0 ) {
			Report(allocation_failed);
			return;
		}
		if ( initialize_elements )
			for (int i = 0; i < bytes; i++)
				data[i] = 0;
	}
	else
		data = 0;
}
//---------------------------------------------------------------------------
mgcImage::
mgcImage (int _type) :
	mgcLattice(0,0),
	element(_type)
{
	Create(_type);
}
//---------------------------------------------------------------------------
mgcImage::
mgcImage (int _type, int _dimensions, const int* initial) :
	mgcLattice(_dimensions,initial),
	element(_type)
{
	Create(_type);
}
//---------------------------------------------------------------------------
mgcImage::
mgcImage (int _type, int _dimensions, int initial_all) :
	mgcLattice(),
	element(_type)
{
	if ( _dimensions == 0 ) {
		Report(zero_dimension);
		return;
	}

	int* initial = new int[_dimensions];
	for (int d = 0; d < _dimensions; d++)
		initial[d] = initial_all;

	*(mgcLattice*)this = mgcLattice(_dimensions,initial);
	Create(_type);
	delete[] initial;
}
//---------------------------------------------------------------------------
mgcImage::
mgcImage (int _type, int _dimensions, int initial0, int initial1, ...) :
	mgcLattice(),
	element(_type)
{
	if ( _dimensions < 2 ) {
		Report(invalid_dimension);
		return;
	}

	int* initial = new int[_dimensions];
	initial[0] = initial0;
	initial[1] = initial1;

	va_list ap;
	va_start(ap,initial1);
	for (int d = 2; d < _dimensions; d++)
		initial[d] = va_arg(ap,int);
	va_end(ap);

	*(mgcLattice*)this = mgcLattice(_dimensions,initial);
	Create(_type);
	delete[] initial;
}
//---------------------------------------------------------------------------
mgcImage::
mgcImage (int _type, const mgcLattice& lattice) :
	mgcLattice(lattice.Dimensions(),lattice.Bounds()),
	element(_type)
{
	Create(_type);
}
//---------------------------------------------------------------------------
mgcImage::
mgcImage (const mgcImage& image) :
	mgcLattice(image),
	element(image.type)
{
	Create(image.type);
	memcpy(data,image.data,quantity*size);
}
//---------------------------------------------------------------------------
mgcImage::
~mgcImage ()
{
	delete[] data;
}
//---------------------------------------------------------------------------
mgcImage::
mgcImage (char* fname, int trgtype) :
	mgcLattice(0,0),
	element(trgtype)
{
	Load(fname,trgtype);
}
//---------------------------------------------------------------------------
mgcImage& mgcImage::
Load (char* fname, int trgtype)
{
	int dims;
	int* dim;
	int srctype;

	mgcImageFile file(fname,&dims,&dim,&srctype);
	if ( file.error ) {
		Report(load_failed);
		return *this;
	}
	if ( !mgcElementDBM::Valid(trgtype) )
		trgtype = srctype;

	if ( *(mgcLattice*)this != mgcLattice(0,0) )
		// destroy old data if a "reload" is attempted
		delete[] data;

	*(mgcLattice*)this = mgcLattice(dims,dim);
	element.type = trgtype;

	if ( initialize_elements ) {
		initialize_elements = 0;
		Create(trgtype);
		initialize_elements = 1;
	}
	else
		Create(trgtype);

	if ( !file.Get(trgtype,data) )
		Report(get_data_failed);

	return *this;
}
//---------------------------------------------------------------------------
mgcImage& mgcImage::
Save (char* fname, int trgtype)
{
	if ( !mgcElementDBM::Valid(trgtype) )
		trgtype = type;

	mgcImageFile file(fname,Dimensions(),Bounds(),trgtype);
	if ( file.error ) {
		Report(save_failed);
		return *this;
	}

	if ( !file.Put(type,data) )
		Report(put_data_failed);
	return *this;
}
//---------------------------------------------------------------------------
mgcImage& mgcImage::
SaveAs (char* fname, int ff, int trgtype)
{
	if ( !mgcElementDBM::Valid(trgtype) )
		trgtype = type;

	mgcImageFile file(fname,Dimensions(),Bounds(),trgtype,ff);
	if ( file.error ) {
		Report(save_failed);
		return *this;
	}

	if ( !file.Put(type,data) )
		Report(put_data_failed);
	return *this;
}
//---------------------------------------------------------------------------
mgcElement mgcImage::
operator[] (int i)
{
	element.data = data+size*i;
	return element;
}
//---------------------------------------------------------------------------
mgcElement mgcImage::
operator() (int x)
{
	element.data = data+size*x;
	return element;
}
//---------------------------------------------------------------------------
mgcElement mgcImage::
operator() (int x, int y)
{
	element.data = data+size*Index(x,y);
	return element;
}
//---------------------------------------------------------------------------
mgcElement mgcImage::
operator() (int x, int y, int z)
{
	element.data = data+size*Index(x,y,z);
	return element;
}
//---------------------------------------------------------------------------
mgcElement mgcImage::
operator() (int x, int y, int z, int r)
{
	element.data = data+size*Index(x,y,z,r);
	return element;
}
//---------------------------------------------------------------------------
mgcElement mgcImage::
operator() (const mgcCoordinate& coordinate)
{
	element.data = data+size*Index(coordinate);
	return element;
}
//---------------------------------------------------------------------------
int mgcImage::
Become (int trgtype)
{
	if ( type == trgtype )
		return 1;

	if ( !mgcElementDBM::Convertible(type,trgtype) ) {
		Report(incompatible_types);
		return 0;
	}

	char* srcdata = data;
	int srctype = type;

	type = element.type = trgtype;
	size = mgcElementDBM::MemorySize(trgtype);

	if ( initialize_elements ) {
		initialize_elements = 0;
		Create(type);
		initialize_elements = 1;
	}
	else
		Create(type);

	mgcElementDBM::Convert(quantity,srctype,srcdata,trgtype,data);
	delete[] srcdata;
	return 1;
}
//---------------------------------------------------------------------------
mgcImage& mgcImage::
operator= (const mgcImage& image)
{
	if ( *(mgcLattice*)this != image ) {
		delete[] data;
		*(mgcLattice*)this = image;
		Create(type);
	}

	if ( !mgcElementDBM::Convertible(image.type,type) ) {
		Report(incompatible_types);
		return *this;
	}

	mgcElementDBM::Convert(quantity,image.type,image.data,type,data);

	return *this;
}
//---------------------------------------------------------------------------
mgcImage& mgcImage::
operator= (const mgcElement& _element)
{
	if ( !mgcElementDBM::Convertible(_element.type,type) ) {
		Report(incompatible_types);
		return *this;
	}

	// convert _element to image type
	mgcElement derived(_element.type);
	derived.data = new char[size];
	derived = _element;

	// copy to each pixel in image
	for (int i = 0; i < quantity; i++)
		memcpy(data+size*i,derived.data,size);

	delete[] (char*)derived.data;

	return *this;
}
//---------------------------------------------------------------------------
int mgcImage::
operator== (const mgcImage& image)
{
	if ( type != image.type )
		return 0;

	if ( *(mgcLattice*)this != image )
		return 0;

	return memcmp(data,image.data,quantity*size) == 0;
}
//---------------------------------------------------------------------------
int mgcImage::
operator== (const mgcElement& _element)
{
	if ( type != _element.type )
		return 0;

	for (int i = 0; i < quantity; i++)
		if ( memcmp(data+size*i,_element.data,size) != 0 )
			return 0;

	return 1;
}
//---------------------------------------------------------------------------
ostream&
operator<< (ostream& ostr, const mgcImage& image)
{
	ostr << "mgcLattice structure:" << endl;
	ostr << *(mgcLattice*)&image;

	ostr << "Image structure:" << endl;

	ostr << "element type = " << mgcElementDBM::Description(image.type)
		 << endl;
	ostr << "element size = " << mgcElementDBM::MemorySize(image.type)
		 << " byte";
	if ( mgcElementDBM::MemorySize(image.type) > 1 )
		ostr << "s";
	ostr << endl;
	ostr << "element pointer = " << ( image.data ? "not null" : "null" )
		 << endl;
	ostr << "initialize elements = "
		 << ( mgcImage::initialize_elements ? "yes" : "no" ) << endl;
	ostr << "verbose = "
		 << ( mgcImage::verbose ? "yes" : "no" ) << endl;

	return ostr;
}
//---------------------------------------------------------------------------
int mgcImage::
Number (unsigned single_error)
{
	int result;
	for (result = -1; single_error; single_error >>= 1)
		result++;
	return result;
}
//---------------------------------------------------------------------------
void mgcImage::
Report (unsigned single_error)
{
	if ( verbose )
		cout << "mgcImage: " << message[Number(single_error)] << endl;
	else
		ofstream("imagbase.err",ios::out|ios::app)
			 << "mgcImage: " << message[Number(single_error)] << endl;

	error |= single_error;
}
//---------------------------------------------------------------------------
void mgcImage::
Report (ostream& ostr)
{
	for (unsigned single_error = 1; single_error; single_error <<= 1)
		if ( error & single_error )
			ostr << "mgcImage: " << message[Number(single_error)] << endl;

	error = 0;
}
//===========================================================================

⌨️ 快捷键说明

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