#include "stdafx.h" #include "DS_1b_cube.h" using namespace std; ///////////////////////////////////////// // There are 2 constructors // create a simple DS_1b_cube from nwZ, nwY, nwX info // create a DS_1b_cube from a BIN file of TYPE //////////////////////////////////////////// // ---------------------------------------------------------------------------------------- // // ---------------------------------------------------------------------------------------- DS_1b_cube::DS_1b_cube(unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { wZ = nwZ; wY = nwY; wX = nwX; dimensions.from_zyx(wZ, wY, wX); AllocateMemory(); } // ---------------------------------------------------------------------------------------- // // ---------------------------------------------------------------------------------------- DS_1b_cube::DS_1b_cube(char* BIN_file, int type, unsigned short int swZ, unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { // Create a new cDS structure unsigned short int x, y, z; wZ = nwZ; wY = nwY; wX = nwX; dimensions.from_zyx(wZ, wY, wX); AllocateMemory(); //if type is cBIN stack if (type == INPUT_IS_CBIN_STACK) { ifstream fin(BIN_file, ios_base::binary); if(!fin.is_open()) { char text[512]; sprintf(text,"cBINs to cDS: error opening cBIN stack file %s", BIN_file); write_to_log(text); } fin.clear(); fin.seekg(0); // Read entire file into memory directly fin.read(reinterpret_cast<char*>(memory), wZ*wY*cwX); fin.close(); } // If type is BIN stack else if (type == INPUT_IS_BIN_STACK) { ifstream fin(BIN_file, ios_base::binary); if(!fin.is_open()) { char text[512]; sprintf(text,"cBINs to cDS: error opening cBIN stack file %s", BIN_file); write_to_log(text); } fin.clear(); fin.seekg(0); // for (z = 0; z < wZ; z++) for (y = 0; y < wY; y++) for (x = 0; x < wX; x++) { if (fin.get()) this->set_spot_1(z, y, x); else this->set_spot_0(z, y, x); } fin.close(); } //if type is BIN files else if (type == INPUT_IS_BIN) { int max_dig = FindNumberOfDigits(swZ+wZ-1); char* inputSlice; for (z = 0; z < wZ; z++) { /* open BIN (z+1) file */ inputSlice = AppendDigitsAndExtension(BIN_file, z+swZ, max_dig, INPUT_IS_BIN); ifstream fin(BIN_file, ios_base::binary); if(!fin.is_open()) { char text[512]; sprintf(text,"cBINs to cDS: error opening cBIN stack file %s", BIN_file); write_to_log(text); } free(inputSlice); /* for each spot in cDS, we will read 8 unsigned chars from the input BIN file and compress */ for (y = 0; y < wY; y++) { for (x = 0; x < wX; x++ ) { if (fin.get()) this->set_spot_1(z,y,x); else this->set_spot_0(z,y,x); }// for X }//for Y fin.close(); // close current slice, go on to next if any left }//for slice } else data = NULL; } DS_1b_cube::DS_1b_cube(DS_cube* orig_cube) { unsigned short int z, y, x; wZ = orig_cube->wZ; wY = orig_cube->wY; wX = orig_cube->wX; dimensions.from_zyx(wZ, wY, wX); AllocateMemory(); //initialize for (z = 0; z < wZ; z++) for (y = 0; y < wY; y++) for (x = 0; x < wX; x++) { if (orig_cube->data[z][y][x] > 0xEF) this->set_spot_1(z, y, x); else this->set_spot_0(z, y, x); } } DS_1b_cube::~DS_1b_cube(void) { delete data; delete rows; delete memory; } // ---------------------------------------------------------------------------------------- // // ---------------------------------------------------------------------------------------- void DS_1b_cube::AllocateMemory() { cwX = (unsigned short int)ceil( (double)wX/8 ); wI = (unsigned long long)8*wZ*wY*cwX; data = new unsigned char ** [wZ]; rows = new unsigned char * [wZ*wY]; memory = new unsigned char [wZ*wY*cwX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_1b_cube::AllocateMemory - out of memory while allocating cube memory."); data = NULL; return; } unsigned short z, y; //make pointers point into correct places for (z = 0; z < wZ; z++) { for (y = 0; y < wY; y++) {//link row point into memory rows rows[z*wY + y] = &memory[z*wY*cwX + y*cwX]; } data[z] = &rows[z*wY]; //link final data pointers into rows } } // ---------------------------------------------------------------------------------------- // // ---------------------------------------------------------------------------------------- bool DS_1b_cube::writeToFile( char* out_file, bool auto_append_extension/*=false*/ ) { char out_file_name[MAX_FILE_STR_LEN]; if ( auto_append_extension ) sprintf( out_file_name, "%s(%d_%d_%d).1b.raw", out_file, wX, wY, wZ); else sprintf( out_file_name, "%s", out_file); ofstream fout( out_file_name, ios_base::binary ); if(!fout.is_open()) { write_to_log("DS_1b_cube::writeToFile - Error opening file %s", out_file_name); return false; } //for (unsigned short int i = 0; i < wZ; i++) // for (unsigned short int y = 0; y < wY; y++) // fout.write(reinterpret_cast<char*>(data[i][y]), cwX); fout.write(reinterpret_cast<char*>(memory), wZ*wY*cwX); fout.close(); return true; //success } // ---------------------------------------------------------------------------------------- // // ---------------------------------------------------------------------------------------- bool DS_1b_cube::readFromFile( char *file_name ) { ifstream fin( file_name, ios_base::binary ); if(!fin.is_open()) { write_to_log( "DS_1b_cube::readFromFile - Error opening file %s", file_name ); return false; } fin.clear(); fin.seekg(0); // Read entire file into memory directly fin.read( reinterpret_cast<char*>(memory), wZ*wY*cwX ); fin.close( ); return true; } // ---------------------------------------------------------------------------------------- // // ---------------------------------------------------------------------------------------- DS_1b_cube* DS_1b_cube::rotate_XY_to_YZ() { unsigned short int ox, oy, nx, ny, nz; int oz; //cause it needs to be -1 at one point unsigned short int nwX, nwY, nwZ; /* define parameters of the new DS */ nwX = wZ; nwY = wY; nwZ = wX; /* make a new cDSinfo struct */ DS_1b_cube * new_ds = new DS_1b_cube(nwZ, nwY, nwX); if (!new_ds){ return NULL; } new_ds->clear(); /* copy the YZ face of original to the XY face of new */ nz = 0; for (ox = 0; ox < wX; ox++){ //slice ny = 0; for (oy = 0; oy < wY; oy++){//row nx = 0; for (oz = (wZ-1); oz >= 0; oz--){//col /* transfer the memory BIT, since cDS is cleared on creation, only do so if '1'*/ if ( this->get_spot((unsigned short)oz, oy, ox) ) new_ds->set_spot_1(nz, ny, nx); nx++; } ny++; } nz++; } return new_ds; } /* function that uses above functions, updates log if errors occur */ DS_1b_cube* DS_1b_cube::rotate_XY_to_ZX() { unsigned short int ox, oy, nx, ny, nz; int oz; //cause it needs to be -1 at one point unsigned short int nwX, nwY, nwZ; /* define parameters of the new DS */ nwX = wX; nwY = wZ; nwZ = wY; /* make a new cDSinfo struct */ DS_1b_cube * new_ds = new DS_1b_cube(nwZ, nwY, nwX); if (!new_ds){ return NULL; } new_ds->clear(); /* copy the XZ face of original to the XY face of new */ nz = 0; for (oy = 0; oy < wY; oy++){ //slice ny = 0; for (oz = (wZ-1); oz >= 0; oz--){//row nx = 0; for (ox = 0; ox < wX; ox++){//col /* transfer the memory BIT, since cDS is cleared on creation, only do so if '1'*/ if ( this->get_spot((unsigned short)oz, oy, ox)) new_ds->set_spot_1(nz, ny, nx); nx++; } ny++; } nz++; } return new_ds; } DS_1b_cube * DS_1b_cube::duplicate() { // unsigned short int i, j, k; DS_1b_cube * new_cube = new DS_1b_cube(wZ, wY, wX); //for (i = 0; i < wZ; i++) // for (j = 0; j < wY; j++) // { // memcpy(new_cube->data[i][j], this->data[i][j], cwX); // } memcpy(new_cube->memory, memory, wZ*wY*cwX); return new_cube; } void DS_1b_cube::invert() { unsigned short int x, y, z; for (z = 0; z < wZ; z++) for (y = 0; y < wY; y++) for (x = 0; x < wX; x++) { if (this->get_spot(z, y, x)) this->set_spot_0(z, y, x); else this->set_spot_1(z, y, x); } } void DS_1b_cube::to_DS_cube(DS_cube * new_cube, unsigned short int first_slice, unsigned short int last_slice) { if ( (new_cube->wX != wX) || (new_cube->wY != wY) || (first_slice < 0) || (last_slice > wZ) ) { write_to_log("DS_1b_cube to DS_cube: error, mismatched bounds."); return; } for (unsigned short int i = first_slice; i <= last_slice; i++) for (unsigned short int j = 0; j < wY; j++) for (unsigned short int k = 0; k < wX; k++) if (this->get_spot(i, j, k)) new_cube->data[i - first_slice][j][k] = 0xFF; else new_cube->data[i - first_slice][j][k] = 0x00; } void DS_1b_cube::to_DS_slice(DS_slice * slice, unsigned short int z_index) { if ( (slice->wX != wX) || (slice->wY != wY) ) { write_to_log("DS_1b_cube to DS_slice: error, mismatched bounds."); return; } for (unsigned short int j = 0; j < wY; j++) for (unsigned short int k = 0; k < wX; k++) if (this->get_spot(z_index, j, k)) slice->data[j][k] = 0xFF; else slice->data[j][k] = 0x00; } void DS_1b_cube::clear() { memset(memory, 0, wZ*wY*cwX); } void DS_1b_cube::setall() { memset(memory, 0xFFFFFFFF, wZ*wY*cwX); } void DS_1b_cube::add_outside_layer(bool b_val) { unsigned short int x, y, z; //allocate a new cube with 1 extra spot on all sides wZ += 2; wY += 2; wX += 2; cwX = (unsigned short int)ceil( (double)wX/8 ); unsigned char *** ndata = new unsigned char ** [wZ]; unsigned char ** nrows = new unsigned char * [wZ*wY]; unsigned char * nmemory = new unsigned char [wZ*wY*cwX]; //make sure memory allocation is successful if (!ndata || !nrows || !nmemory) { write_to_log("DS_1b_cube: out of memory while creating new cube."); data = NULL; return; } //make pointers point into correct places for (z = 0; z < wZ; z++) { for (y = 0; y < wY; y++) //link row point into memory rows nrows[z*wY + y] = &nmemory[z*wY*cwX + y*cwX]; ndata[z] = &nrows[z*wY]; //link final data pointers into rows } //copy over values unsigned char charLoc; unsigned short int charOff; for (z = 1; z < (wZ-1); z++) for (y = 1; y < (wY-1); y++) for (x = 1; x < (wX-1); x++) { if (this->get_spot(z, y, x)) { charLoc = (unsigned char)(x%8); charOff = x/8; if ( (unsigned char)(data[z][y][charOff] << charLoc) < 128) ndata[z][y][charOff] |= (unsigned char)(128 >> charLoc); } else { charLoc = (unsigned char)(x%8); charOff = x/8; if ( (unsigned char)(data[z][y][charOff] << charLoc) > 127) ndata[z][y][charOff] &= (unsigned char)(~(128 >> charLoc)); } } //add outside layers for (z = 0; z < wZ; z += (wZ-1)) for (y = 0; y < wY; y += (wY-1)) for (x = 0; x < wX; x += (wX-1)) { if (b_val) { charLoc = (unsigned char)(x%8); charOff = x/8; if ( (unsigned char)(data[z][y][charOff] << charLoc) < 128) ndata[z][y][charOff] |= (unsigned char)(128 >> charLoc); } else { charLoc = (unsigned char)(x%8); charOff = x/8; if ( (unsigned char)(data[z][y][charOff] << charLoc) > 127) ndata[z][y][charOff] &= (unsigned char)(~(128 >> charLoc)); } } //update pointers delete data; delete rows; delete memory; memory = nmemory; data = ndata; rows = nrows; }