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

📄 imagfile.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
#include <stdio.h>
#include <fstream.h>
#include "imagfile.h"

// error handling
int mgcImageFile::verbose = 0;
unsigned mgcImageFile::error = 0;
const unsigned mgcImageFile::file_open_failed      = 0x00000001;
const unsigned mgcImageFile::format_not_recognized = 0x00000002;
const unsigned mgcImageFile::get_head_failed       = 0x00000004;
const unsigned mgcImageFile::put_head_failed       = 0x00000008;
const unsigned mgcImageFile::invalid_data_access   = 0x00000010;
const unsigned mgcImageFile::get_data_failed       = 0x00000020;
const unsigned mgcImageFile::put_data_failed       = 0x00000040;
const unsigned mgcImageFile::incompatible_types    = 0x00000080;
const char* mgcImageFile::message[8] = {
	"attempt to open file failed",
	"format not recognized",
	"attempt to read file header failed",
	"attempt to write file header failed",
	"data block has invalid offset and/or quantity",
	"attempt to read file data failed",
	"attempt to write file data failed",
	"incompatible memory and file types"
};

//===========================================================================
mgcImageFile::
mgcImageFile (char* name, int* dims, int** dim, int* eltype)
{
	io_dim = 0;
	io_name = 0;

	int result = mgcFileFormat::Query(name);
	if ( result == mgcFileFormat::not_openable ) {
		Report(file_open_failed);
		return;
	}
	if ( result == mgcFileFormat::not_recognized ) {
		Report(format_not_recognized);
		return;
	}

	io_rff = mgcFileFormat::RFF(result);

	char* elform = new char[256];  // assumes length(description) < 256
	if ( !io_rff.gethead(name,dims,dim,elform,&io_file_order) ) {
		Report(get_head_failed);
		delete[] elform;
		return;
	}
	*eltype = mgcElementDBM::Type(elform);
	delete[] elform;

	// copy file name
	int length;
	for (length = 0; name[length]; length++)
		;
	io_name = new char[length+1];
	int i;
	for (i = 0; i <= length; i++)
		io_name[i] = name[i];

	// copy data parameters
	io_dims = *dims;
	io_dim = *dim;
	io_quantity = 1;
	for (i = 0; i < io_dims; i++)
		io_quantity *= io_dim[i];
	io_file_type = *eltype;
}
//---------------------------------------------------------------------------
mgcImageFile::
mgcImageFile (char* name, int dims, const int* dim, int eltype,
	int fformat)
{
	io_dim = 0;
	io_name = 0;

	if ( fformat < 0 )
		io_rff = mgcFileFormat::RFF(mgcFileFormat::default_format);
	else if ( mgcFileFormat::Valid(fformat) )
		io_rff = mgcFileFormat::RFF(fformat);
	else {
		Report(format_not_recognized);
		return;
	}

	io_file_order = mgcElementDBM::ByteOrder();
	if ( dims == 0 ) {
		Report(put_head_failed);
		return;
	}
	const char* descr = mgcElementDBM::Description(eltype);
	if ( !io_rff.puthead(name,dims,dim,descr,io_file_order) ) {
		Report(put_head_failed);
		return;
	}

	// copy file name
	int length;
	for (length = 0; name[length]; length++)
		;
	io_name = new char[length+1];
	int i;
	for (i = 0; i <= length; i++)
		io_name[i] = name[i];

	// copy data parameters
	io_dims = dims;
	io_dim = new int[io_dims];
	io_quantity = 1;
	for (i = 0; i < io_dims; i++) {
		io_dim[i] = dim[i];
		io_quantity *= io_dim[i];
	}
	io_file_type = eltype;
}
//---------------------------------------------------------------------------
mgcImageFile::
~mgcImageFile ()
{
	if ( io_dim )
		delete[] io_dim;
	if ( io_name )
	    delete[] io_name;
}
//---------------------------------------------------------------------------
int mgcImageFile::
Get (int memory_type, void* pbuf, long offset, int quantity)
{
	// io_file_type, io_quantity, io_name, io_file_order

	if ( !mgcElementDBM::Convertible(io_file_type,memory_type) ) {
		Report(incompatible_types);
		return 0;
	}

	if ( quantity < 0 )
		quantity = io_quantity;

	if ( offset < 0 || offset+quantity > io_quantity ) {
		Report(invalid_data_access);
		return 0;
	}

	const unsigned el_cnt = 4096;
	int block_cnt = quantity / el_cnt;
	int el_rem = quantity % el_cnt;

	int fsize = mgcElementDBM::MemorySize(io_file_type);
	int msize = mgcElementDBM::MemorySize(memory_type);
	int fbuf_size = el_cnt*fsize;
	int pbuf_size = el_cnt*msize;
	char* fbuf = new char[fbuf_size];

	int packed_fsize = mgcElementDBM::PackedSize(io_file_type);
	int packed_fbuf_size = el_cnt*packed_fsize;
	long packed_offset = offset*packed_fsize;
	int packed_remaining = el_rem*packed_fsize;

	char* cpbuf = (char*) pbuf;
	for (int i = 0; i < block_cnt; i++) {
		if ( !io_rff.getdata(io_name,packed_offset,packed_fbuf_size,fbuf) ) {
			Report(get_data_failed);
			delete[] fbuf;
			return 0;
		}

		mgcElementDBM::Unpack(el_cnt,io_file_type,fbuf);

		if ( io_file_order != mgcElementDBM::ByteOrder() )
			mgcElementDBM::Reverse(el_cnt,io_file_type,fbuf);

		mgcElementDBM::Convert(el_cnt,io_file_type,fbuf,memory_type,cpbuf);

		cpbuf += pbuf_size;
		packed_offset += packed_fbuf_size;
	}
	if ( el_rem ) {
		if ( !io_rff.getdata(io_name,packed_offset,packed_remaining,fbuf) ) {
			Report(get_data_failed);
			delete[] fbuf;
			return 0;
		}

		mgcElementDBM::Unpack(el_rem,io_file_type,fbuf);

		if ( io_file_order != mgcElementDBM::ByteOrder() )
			mgcElementDBM::Reverse(el_rem,io_file_type,fbuf);

		mgcElementDBM::Convert(el_rem,io_file_type,fbuf,memory_type,cpbuf);
	}

	delete[] fbuf;
	return 1;
}
//---------------------------------------------------------------------------
int mgcImageFile::
Put (int memory_type, void* pbuf, long offset, int quantity)
{
	// io_file_type, io_quantity, io_name, io_file_order

	if ( !mgcElementDBM::Convertible(memory_type,io_file_type) ) {
		Report(incompatible_types);
		return 0;
	}

	if ( quantity < 0 )
		quantity = io_quantity;

	if ( offset < 0 || offset+quantity > io_quantity ) {
		Report(invalid_data_access);
		return 0;
	}

	const unsigned el_cnt = 4096;  // elements-per-block to process
	int block_cnt = quantity / el_cnt;
	int el_rem = quantity % el_cnt;

	int fsize = mgcElementDBM::MemorySize(io_file_type);
	int msize = mgcElementDBM::MemorySize(memory_type);
	int fbuf_size = el_cnt*fsize;
	int pbuf_size = el_cnt*msize;
	char* fbuf = new char[fbuf_size];

	int packed_fsize = mgcElementDBM::PackedSize(io_file_type);
	int packed_fbuf_size = el_cnt*packed_fsize;
	long packed_offset = offset*packed_fsize;
	int packed_remaining = el_rem*packed_fsize;

	char* cpbuf = (char*) pbuf;
	for (int i = 0; i < block_cnt; i++) {
		mgcElementDBM::Convert(el_cnt,memory_type,cpbuf,io_file_type,fbuf);

		if ( io_file_order != mgcElementDBM::ByteOrder() )
			mgcElementDBM::Reverse(el_cnt,io_file_type,fbuf);

		mgcElementDBM::Pack(el_cnt,io_file_type,fbuf);

		if ( !io_rff.putdata(io_name,packed_offset,packed_fbuf_size,fbuf) ) {
			Report(put_data_failed);
			delete[] fbuf;
			return 0;
		}

		cpbuf += pbuf_size;
		packed_offset += packed_fbuf_size;
	}
	if ( el_rem ) {
		mgcElementDBM::Convert(el_rem,memory_type,cpbuf,io_file_type,fbuf);

		if ( io_file_order != mgcElementDBM::ByteOrder() )
			mgcElementDBM::Reverse(el_rem,io_file_type,fbuf);

		mgcElementDBM::Pack(el_rem,io_file_type,fbuf);

		if ( !io_rff.putdata(io_name,packed_offset,packed_remaining,fbuf) ) {
			Report(put_data_failed);
			delete[] fbuf;
			return 0;
		}
	}

	delete[] fbuf;
	return 1;
}
//---------------------------------------------------------------------------
int mgcImageFile::
Get (void* message)
{
	if ( io_rff.getmessage == 0 )
		return 0;
	else
		return io_rff.getmessage(io_name,message);
}
//---------------------------------------------------------------------------
int mgcImageFile::
Put (void* message)
{
	if ( io_rff.putmessage == 0 )
		return 0;
	else
		return io_rff.putmessage(io_name,message);
}
//---------------------------------------------------------------------------
int mgcImageFile::
Number (unsigned single_error)
{
	int result;
	for (result = -1; single_error; single_error >>= 1)
		result++;
	return result;
}
//---------------------------------------------------------------------------
void mgcImageFile::
Report (unsigned single_error)
{
	if ( verbose )
		cout << "mgcImageFile: " << message[Number(single_error)] << endl;
	else
		ofstream("imagfile.err",ios::out|ios::app)
			 << "mgcImageFile: " << message[Number(single_error)] << endl;

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

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

⌨️ 快捷键说明

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