#include "stdafx.h" #include "DS_cube.h" ///////////////////////////////////////////////////////////////////////////////////////////// // UNSIGNED CHAR CUBE ///////////////////////////////////////////////////////////////////////////////////////////// DS_cube::DS_cube(unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { unsigned short int y, z; wZ = nwZ; wY = nwY; wX = nwX; data = new unsigned char ** [wZ]; rows = new unsigned char * [wZ*wY]; memory = new unsigned char [wZ*wY*wX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_cube: out of memory while creating 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 rows[z*wY + y] = &memory[z*wY*wX + y*wX]; data[z] = &rows[z*wY]; //link final data pointers into rows } } DS_cube::DS_cube(Photoinfo* info, void* /*dlg_share*/) { unsigned short int y, z; unsigned char max_dig = (unsigned char)FindNumberOfDigits(info->startofz + info->sizeofz - 1); wZ = info->sizeofz; wY = info->sizeofy; wX = info->sizeofx; //setup the progress bar parameters // PoroMediaDialogShare * dlg = (PoroMediaDialogShare*) dlg_share; // dlg->pbar_simulation_progress.SetRange(0, wZ); // dlg->pbar_simulation_progress.SetPos(0); // dlg->pbar_simulation_progress.SetStep(1); data = new unsigned char ** [wZ]; rows = new unsigned char * [wZ*wY]; memory = new unsigned char [wZ*wY*wX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_cube: out of memory while creating 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 rows[z*wY + y] = &memory[z*wY*wX + y*wX]; data[z] = &rows[z*wY]; //link final data pointers into rows } //if input is multiple RAW files if (info->type == INPUT_IS_RAW) { char* infile; for (z = info->startofz; z < (info->startofz + wZ); z++) { //determine digits used in current slice name infile = AppendDigitsAndExtension(info->raw_prefix, z, max_dig, INPUT_IS_RAW); //open the slice ifstream fin(infile, ios_base::binary); if(!fin.is_open()) { char log_txt[512]; sprintf(log_txt, "DS_cube: error: cannot open input file %s", infile); write_to_log(log_txt); return; } //read images into memory fin.clear(); fin.seekg(0); //for (y = 0; y < wY; y++) // fin.read(reinterpret_cast<char*>(data[z-info->startofz][y]), wX); fin.read(reinterpret_cast<char*>(data[z - info->startofz][0]), wY*wX); fin.close(); free(infile); //update progress bar // dlg->pbar_simulation_progress.StepIt(); }//END for each slice }//END if INPUT_IS_RAW else { //other wise input is a RAW STACK //open source images, since its a stack we attach a .stack.raw extension char infile[512]; sprintf(infile,"%s",info->raw_prefix); ifstream fin(infile, ios_base::binary); if(!fin.is_open()) { char log_txt[512]; sprintf(log_txt, "DS_cube: error: cannot open input file %s", infile); write_to_log(log_txt); return; } //for each slice //for (z = 0; z < wZ; z++) //{ // //read images into memory // for (y = 0; y < wY; y++) // fin.read(reinterpret_cast<char*>(data[z][y]), wX); //} fin.read(reinterpret_cast<char*>(memory), wZ*wY*wX); fin.close(); } } DS_cube::~DS_cube(void) { delete data; delete rows; delete memory; } void DS_cube::clear() { //for (unsigned short int i = 0; i < wZ; i++) // for (unsigned short int j = 0; j < wY; j++) memset(memory, 0, wZ*wY*wX); } DS_cube* DS_cube::duplicate() { DS_cube* new_cube = new DS_cube(wZ, wY, wX); //for (unsigned short int i = 0; i < wZ; i++) // for (unsigned short int j = 0; j < wY; j++) memcpy(new_cube->memory, memory, wZ*wY*wX);//memcpy(new_cube->data[i][j], data[i][j], wX); return new_cube; } void DS_cube::to_DS_slice(DS_slice* slice, unsigned short int z_index) { //for (unsigned short int j = 0; j < wY; j++) memcpy(slice->memory, data[z_index][0], wY*wX); } void DS_cube::to_DS_slicex(DS_slice* slice, unsigned short int x_index) { for (unsigned short int k = 0; k < wZ; k++) for (unsigned short int j = 0; j < wY; j++) slice->data[k][j] = data[k][j][x_index]; } void DS_cube::to_DS_slicey(DS_slice* slice, unsigned short int y_index) { for (unsigned short int k = 0; k < wZ; k++) for (unsigned short int i = 0; i < wX; i++) slice->data[k][i] = data[k][y_index][i]; } void DS_cube::copy_DS_slice(DS_slice* slice, unsigned short int z_index) { //for (unsigned short int j = 0; j < wY; j++) memcpy(data[z_index][0], slice->memory, wY*wX); } void DS_cube::copy_DS_slicex(DS_slice* slice, unsigned short int x_index) { for (unsigned short int k = 0; k < wZ; k++) for (unsigned short int j = 0; j < wY; j++) data[k][j][x_index] = slice->data[k][j]; } void DS_cube::copy_DS_slicey(DS_slice* slice, unsigned short int y_index) { for (unsigned short int k = 0; k < wZ; k++) for (unsigned short int i = 0; i < wX; i++) data[k][y_index][i] = slice->data[k][i]; } void DS_cube::copy_DS_slicez_float(DS_slice_f* slice, unsigned short int z_index) { for (unsigned short int i = 0; i < wY; i++) for (unsigned short int j = 0; j < wX; j++) data[z_index][i][j] = (unsigned char)(slice->data[i][j] + 0.5); } void DS_cube::to_DS_slicez_float(DS_slice_f* slice, unsigned short int z_index) { for (unsigned short int i = 0; i < wY; i++) for (unsigned short int j = 0; j < wX; j++) slice->data[i][j] = data[z_index][i][j]; } void DS_cube::resize_enveloppe(unsigned short int z_index, unsigned short int y_index, unsigned short int x_index) {//resize cube by removing []_index on the enveloppe of the cube unsigned short int wZ2, wY2, wX2; wZ2 = wZ - 2*z_index; wY2 = wY - 2*y_index; wX2 = wX - 2*x_index; unsigned short int y, z; for (z = 0; z < wZ2; z++) for (y = 0; y < wY2; y++) { //memcpy(&data[z][y][0], &data[z+z_index][y+y_index][x_index], wX-2*x_index); memcpy(&memory[z*wY2*wX2 + y*wX2], &memory[(z+z_index)*wY*wX + (y+y_index)*wX + x_index], wX2); } //update new cube dimensions wZ = wZ2; wY = wY2; wX = wX2; } void DS_cube::resize_ends(unsigned short int z_index, unsigned short int y_index, unsigned short int x_index) {//resize cube by []_index at end (x+,y+,z+) unsigned short int wZ2, wY2, wX2; wZ2 = wZ - z_index; wY2 = wY - y_index; wX2 = wX - x_index; unsigned short int y, z; for (z = 0; z < wZ2; z++) for (y = 0; y < wY2; y++) memcpy(&memory[z*wY2*wX2 + y*wX2], &memory[(z+z_index)*wY*wX + (y+y_index)*wX], wX2); //update new cube dimensions wZ = wZ2; wY = wY2; wX = wX2; } void DS_cube::resize_multiple(unsigned char multiple) {//resize cube so its new dimensions are a multiple of 'multiple' for compatibility (e.g. mpeg4 compression) unsigned short int z_index, y_index, x_index; z_index = wZ % multiple; y_index = wY % multiple; x_index = wX % multiple; resize_ends(z_index, y_index, x_index); } //'draws' a linear line from start to end coord using 'mark_val', returns 1 or 2 if invalid coordinates given (out of range) int DS_cube::mark_a_line(Vect3usi &start_coord, Vect3usi &end_coord, unsigned char mark_val) { if ( (start_coord.z >= wZ) || (start_coord.y >= wY) || (start_coord.x >= wX) ) return 1; if ( (end_coord.z >= wZ) || (end_coord.y >= wY) || (end_coord.x >= wX) ) return 2; unsigned short z, y, x; Vect3usi vector; char dz, dy, dx;//, xl, xg, yl, yg, zl, zg; start_coord.to_zyx(z, y, x); while ( (z != end_coord.z) || (y != end_coord.y) || (x != end_coord.x) ) { //mark spot data[z][y][x] = mark_val; //find direction to move in vector.from_zyx(z, y, x); vector.get_unit_direction_to(end_coord, dz, dy, dx); z = z+dz; y = y+dy; x = x+dx; } //mark end spot data[z][y][x] = mark_val; return 0; } bool DS_cube::write_to_RAW_STACK(char* file_name) { ofstream fout(file_name, ios_base::binary); if(!fout.is_open()) { char text[512]; sprintf(text,"DS_cube::write_RAW_STACK: error opening RAW stack file %s", file_name); write_to_log(text); return false; } //for (unsigned short int i = 0; i < wZ; i++) // for (unsigned short int j = 0; j < wY; j++) // fout.write(reinterpret_cast<char*>(data[i][j]), wX); fout.write(reinterpret_cast<char*>(memory), wZ*wY*wX); fout.close(); return true; //success } bool DS_cube::read_from_RAW_STACK(char* file_name) {//this function assumes file to open has same dimensions as current cube ifstream fin(file_name, ios_base::binary); if(!fin.is_open()) { char log_txt[512]; sprintf(log_txt, "DS_cube: read file error: cannot open input file %s", file_name); write_to_log(log_txt); return false; } fin.read(reinterpret_cast<char*>(memory), wZ*wY*wX); fin.close(); return true; } bool DS_cube::read_slice_from_RAW_STACK(char *file_name, unsigned short z_index_src, unsigned short z_index_dst) {//this function assumes file to open has same dimensions as current cube if (z_index_dst >= wZ) { char log_txt[512]; sprintf(log_txt, "DS_cube: read slice error: z_index_dst larger than size of stack", file_name); write_to_log(log_txt); return false; } ifstream fin(file_name, ios_base::binary); if(!fin.is_open()) { char log_txt[512]; sprintf(log_txt, "DS_cube: read file error: cannot open input file %s", file_name); write_to_log(log_txt); return false; } fin.seekg(z_index_src*wX*wY); fin.read(reinterpret_cast<char*>(memory+wY*wX*z_index_dst), wY*wX); fin.close(); return true; } ///////////////////////////////////////////////////////////////////////////////////////////// // SIGNED SHORT INT CUBE ///////////////////////////////////////////////////////////////////////////////////////////// DS_si_cube::DS_si_cube(unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { register unsigned short int y, z; wZ = nwZ; wY = nwY; wX = nwX; data = new short int ** [wZ]; rows = new short int * [wZ*wY]; memory = new short int [wZ*wY*wX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_cube: out of memory while creating 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 rows[z*wY + y] = &memory[z*wY*wX + y*wX]; data[z] = &rows[z*wY]; //link final data pointers into rows } } DS_si_cube::~DS_si_cube(void) { delete data; delete rows; delete memory; } void DS_si_cube::clear() { for (unsigned short int i = 0; i < wZ; i++) for (unsigned short int j = 0; j < wY; j++) for (unsigned short int k = 0; k < wX; k++) data[i][j][k] = 0; } bool DS_si_cube::write_to_siRAW_STACK(char* file_name) { //create file ofstream fout(file_name, ios_base::binary); if(!fout.is_open()) { char log_txt[512]; sprintf(log_txt, "DS_si_cube: error: cannot open output file %s", file_name); write_to_log(log_txt); return false; } fout.write((char*)memory, wX*wY*wZ*sizeof(short)); //for (unsigned short z = 0; z < wZ; z++) // for (unsigned short y = 0; y < wY; y++) // for (unsigned short x = 0; x < wX; x++) // { // fout.put((char)(data[z][y][x] >> 8)); // fout.put((char)(data[z][y][x] & 0x00FF)); // // //fout.write((char*)(&cur_shade), sizeof(unsigned short)); // } fout.close(); return true; //success } ///////////////////////////////////////////////////////////////////////////////////////////// // UNSIGNED SHORT INT CUBE ///////////////////////////////////////////////////////////////////////////////////////////// DS_usi_cube::DS_usi_cube(unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { register unsigned short int y, z; wZ = nwZ; wY = nwY; wX = nwX; data = new unsigned short int ** [wZ]; rows = new unsigned short int * [wZ*wY]; memory = new unsigned short int [wZ*wY*wX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_cube: out of memory while creating 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 rows[z*wY + y] = &memory[z*wY*wX + y*wX]; data[z] = &rows[z*wY]; //link final data pointers into rows } } DS_usi_cube::~DS_usi_cube(void) { delete data; delete rows; delete memory; } void DS_usi_cube::clear() { for (unsigned short int i = 0; i < wZ; i++) for (unsigned short int j = 0; j < wY; j++) for (unsigned short int k = 0; k < wX; k++) data[i][j][k] = 0; } void DS_usi_cube::flood_with_new_val(unsigned short z, unsigned short y, unsigned short x, unsigned short new_val) { char dz, dy, dx, xl=-1, xg=1, yl=-1, yg=1, zl=-1, zg=1; //grab current code unsigned short spot_val = data[z][y][x]; //mark current spot with new Val data[z][y][x] = new_val; //bound check if (x < 1) xl = 0; if (y < 1) yl = 0; if (z < 1) zl = 0; if (x > wX-2) xg = 0; if (y > wY-2) yg = 0; if (z > wZ-2) zg = 0; //flood ID to neighs for (dz = zl; dz <= zg; dz++) for (dy = yl; dy <= yg; dy++) for (dx = xl; dx <= xg; dx++) { if (data[z+dz][y+dy][x+dx] == spot_val) flood_with_new_val(z+dz, y+dy, x+dx, new_val); } } bool DS_usi_cube::write_to_usiRAW_STACK(char* file_name) { //create file ofstream fout(file_name, ios_base::binary); if(!fout.is_open()) { char log_txt[512]; sprintf(log_txt, "DS_usi_cube: error: cannot open output file %s", file_name); write_to_log(log_txt); return false; } fout.write((char*)memory, wX*wY*wZ*sizeof(unsigned short)); //for (unsigned short z = 0; z < wZ; z++) // for (unsigned short y = 0; y < wY; y++) // for (unsigned short x = 0; x < wX; x++) // { // fout.put((char)(data[z][y][x] >> 8)); // fout.put((char)(data[z][y][x] & 0x00FF)); // // //fout.write((char*)(&cur_shade), sizeof(unsigned short)); // } fout.close(); return true; //success } ///////////////////////////////////////////////////////////////////////////////////////////// // UNSIGNED SHORT INT CUBE ///////////////////////////////////////////////////////////////////////////////////////////// DS_f_cube::DS_f_cube(unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { register unsigned short int y, z; wZ = nwZ; wY = nwY; wX = nwX; data = new float ** [wZ]; rows = new float * [wZ*wY]; memory = new float [wZ*wY*wX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_cube: out of memory while creating 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 rows[z*wY + y] = &memory[z*wY*wX + y*wX]; data[z] = &rows[z*wY]; //link final data pointers into rows } } DS_f_cube::~DS_f_cube(void) { delete data; delete rows; delete memory; } void DS_f_cube::clear() { for (unsigned short int i = 0; i < wZ; i++) for (unsigned short int j = 0; j < wY; j++) for (unsigned short int k = 0; k < wX; k++) data[i][j][k] = 0.0f; } ///////////////////////////////////////////////////////////////////////////////////////////// // UNSIGNED LONG LONG CUBE ///////////////////////////////////////////////////////////////////////////////////////////// DS_ull_cube::DS_ull_cube(unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { register unsigned short int y, z; wZ = nwZ; wY = nwY; wX = nwX; data = new unsigned long long ** [wZ]; rows = new unsigned long long * [wZ*wY]; memory = new unsigned long long [wZ*wY*wX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_cube: out of memory while creating 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 rows[z*wY + y] = &memory[z*wY*wX + y*wX]; data[z] = &rows[z*wY]; //link final data pointers into rows } } DS_ull_cube::~DS_ull_cube(void) { delete data; delete rows; delete memory; } void DS_ull_cube::clear() { for (unsigned short int i = 0; i < wZ; i++) for (unsigned short int j = 0; j < wY; j++) for (unsigned short int k = 0; k < wX; k++) data[i][j][k] = 0; } ///////////////////////////////////////////////////////////////////////////////////////////// // SIGNED CHAR CUBE ///////////////////////////////////////////////////////////////////////////////////////////// DS_c_cube::DS_c_cube(unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { unsigned short int y, z; wZ = nwZ; wY = nwY; wX = nwX; data = new signed char ** [wZ]; rows = new signed char * [wZ*wY]; memory = new signed char [wZ*wY*wX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_cube: out of memory while creating 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 rows[z*wY + y] = &memory[z*wY*wX + y*wX]; data[z] = &rows[z*wY]; //link final data pointers into rows } } DS_c_cube::~DS_c_cube(void) { delete data; delete rows; delete memory; } void DS_c_cube::clear() { for (unsigned short int i = 0; i < wZ; i++) for (unsigned short int j = 0; j < wY; j++) for (unsigned short int k = 0; k < wX; k++) data[i][j][k] = 0; } ///////////////////////////////////////////////////////////////////////////////////////////// // INT CUBE ///////////////////////////////////////////////////////////////////////////////////////////// DS_i_cube::DS_i_cube(unsigned short int nwZ, unsigned short int nwY, unsigned short int nwX) { unsigned short int y, z; wZ = nwZ; wY = nwY; wX = nwX; data = new int ** [wZ]; rows = new int * [wZ*wY]; memory = new int [wZ*wY*wX]; //make sure memory allocation is successful if (!data || !rows || !memory) { write_to_log("DS_cube: out of memory while creating 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 rows[z*wY + y] = &memory[z*wY*wX + y*wX]; data[z] = &rows[z*wY]; //link final data pointers into rows } } DS_i_cube::~DS_i_cube(void) { delete data; delete rows; delete memory; } void DS_i_cube::clear() { for (unsigned short int i = 0; i < wZ; i++) for (unsigned short int j = 0; j < wY; j++) for (unsigned short int k = 0; k < wX; k++) data[i][j][k] = 0; }