rtsVolume.cpp 5.71 KB
#include "rtsVolume.h"

rtsVolume::rtsVolume()
{
	m_data = NULL;
	m_size_x = 0;
	m_size_y = 0;
	m_size_z = 0;
}

rtsVolume::rtsVolume(unsigned int size_x, unsigned int size_y, unsigned int size_z)
{
	m_size_x = size_x;
	m_size_y = size_y;
	m_size_z = size_z;

	//allocate space for the data
	m_data = new unsigned char[m_size_x * m_size_y * m_size_z];
	for(int i=0; i<m_size_x*m_size_y*m_size_z; i++)
		m_data[i] = 0;
}

rtsVolume::rtsVolume(const unsigned char* data, unsigned int size_x, unsigned int size_y, unsigned int size_z)
{
	//assign variables
	m_size_x = size_x;
	m_size_y = size_y;
	m_size_z = size_z;
	//allocate data
	m_data = new unsigned char[m_size_x * m_size_y * m_size_z];
	//blit data
	blit3D(data, m_size_x, m_size_y, m_size_z, m_data, 0,0,0,m_size_x, m_size_y, m_size_z);

}

rtsVolume::~rtsVolume()
{
	delete m_data;
}

void rtsVolume::open(const char *filename)
{
	if(m_data != NULL)
		delete m_data;
	

	ifstream infile(filename, ios::in | ios::binary);

	//load the dimensions of the data set
	infile.read((char*)&m_size_x, sizeof(int));
	infile.read((char*)&m_size_y, sizeof(int));
	infile.read((char*)&m_size_z, sizeof(int));

	m_data = new unsigned char[m_size_x*m_size_y*m_size_z];
	infile.read((char*)m_data, m_size_x*m_size_y*m_size_z*sizeof(unsigned char));

	//calculate min and maxes
	infile.close();
}

void rtsVolume::save(const char *filename)
{
	ofstream outfile(filename, ios::out | ios::binary);
	outfile.write((char*)&m_size_x, sizeof(int));
	outfile.write((char*)&m_size_y, sizeof(int));
	outfile.write((char*)&m_size_z, sizeof(int));

	outfile.write((char*)m_data, m_size_x*m_size_y*m_size_z*sizeof(unsigned char));
	outfile.close();
}

void rtsVolume::resize_canvas(unsigned int size_x, unsigned int size_y, unsigned int size_z)
{
	//allocate memory for the new size
	unsigned char* temp = m_data;
	m_data = new unsigned char[size_x * size_y * size_z];

	//copy the data from old (temp) to new (m_data)
	blit3D(temp, m_size_x, m_size_y, m_size_z, m_data, 0, 0, 0, size_x, size_y, size_z);

	//set the size variables
	m_size_x = size_x;
	m_size_y = size_y;
	m_size_z = size_z;

}

void rtsVolume::blacken_border()
{
	//code to put a black border around the volume
	//create a few volumes for each side of the cube
	rtsVolume front_back(m_size_x, m_size_y, 1);
	rtsVolume left_right(1, m_size_y, m_size_z);
	rtsVolume top_bottom(m_size_x, 1, m_size_z);

	//copy these into the current object
	this->insert(front_back, 0, 0, 0);
	this->insert(front_back, 0, 0, m_size_z-1);
	this->insert(left_right, 0, 0, 0);
	this->insert(left_right, m_size_x-1, 0, 0);
	this->insert(top_bottom, 0, 0, 0);
	this->insert(top_bottom, 0, m_size_y-1, 0);

}

void rtsVolume::invert()
{
	//inverts the data stored in the volume
	unsigned int length = m_size_x*m_size_y*m_size_z;
	for(int i=0; i<length; i++)
		m_data[i] = 255 - m_data[i];
}

void rtsVolume::blacken(unsigned char threshold)
{
	unsigned int size = m_size_x*m_size_y*m_size_z;
	for(unsigned int i=0; i<size; i++)
		if(m_data[i] <= threshold)
			m_data[i] = 0;
}

void rtsVolume::whiten(unsigned char threshold)
{
	unsigned int size = m_size_x*m_size_y*m_size_z;
	for(unsigned int i=0; i<size; i++)
		if(m_data[i] >= threshold)
			m_data[i] = 255;
}

void rtsVolume::blit3D(const unsigned char* source,
				   unsigned int s_sx, unsigned int s_sy, unsigned int s_sz,
				   unsigned char* dest,
				   unsigned int d_px, unsigned int d_py, unsigned int d_pz,
				   unsigned int d_sx, unsigned int d_sy, unsigned int d_sz)
{
	unsigned int ps, pd;		//stores the mapping for the source point to the dest point
	//find the maximum points that can be blit to (in case source overlaps the edges of dest)
	unsigned int blit_size_x = min(s_sx, d_sx - d_px);
	unsigned int blit_size_y = min(s_sy, d_sy - d_py);
	unsigned int blit_size_z = min(s_sz, d_sz - d_pz);

	unsigned int source_z_offset = s_sx * s_sy;
	unsigned int dest_z_offset = d_sx * d_sy;

	unsigned int z,y;
	for(z=0; z<blit_size_z; z++)
		for(y=0; y<blit_size_y; y++)
		{
			ps = z * source_z_offset + y * s_sx;
			pd = (z + d_pz) * dest_z_offset + (y + d_py) * d_sx + d_px;
			memcpy((void*)(&dest[pd]), (void*)(&source[ps]), sizeof(unsigned char)*blit_size_x);
		}



}

inline unsigned char rtsVolume::operator ()(unsigned int x, unsigned int y, unsigned int z)
{
	return m_data[z * m_size_x * m_size_y + y * m_size_x + z];
}

rtsVolume& rtsVolume::operator=(const rtsVolume& rhs)
{
	//check for self-assignment
	if(this == &rhs)
		return *this;

	//deallocate memory
	if(m_data != NULL)
		delete m_data;

	//copy variables
	m_size_x = rhs.m_size_x;
	m_size_y = rhs.m_size_y;
	m_size_z = rhs.m_size_z;

	//allocate and copy memory
	m_data = new unsigned char[m_size_x * m_size_y * m_size_z];
	//copy the data
	blit3D(rhs.m_data, m_size_x, m_size_y, m_size_z,m_data, 0, 0, 0, m_size_x, m_size_y, m_size_z);

	//return the left hand side
	return *this;
}


rtsVolume::rtsVolume(const rtsVolume& original)
{
	//copy the shallow variables
	m_size_x = original.m_size_x;
	m_size_y = original.m_size_y;
	m_size_z = original.m_size_z;

	//allocate space for the data
	m_data = new unsigned char[m_size_x * m_size_y * m_size_z];
	//copy the data
	blit3D(original.m_data, m_size_x, m_size_y, m_size_z,m_data, 0, 0, 0, m_size_x, m_size_y, m_size_z);
}

unsigned char* rtsVolume::get_bits()
{
	return m_data;
}

void rtsVolume::insert(rtsVolume source, unsigned int pos_x, unsigned int pos_y, unsigned int pos_z)
{
	unsigned char* source_bits = source.get_bits();
	blit3D(source_bits, source.get_dimx(), source.get_dimy(), source.get_dimz(), 
		m_data, pos_x, pos_y, pos_z, m_size_x, m_size_y, m_size_z);
}