//------------------------------------------------------------------------------------ // DSt_cube<T>::writeToFile // Description - Writes cube to a file in its RAW form //------------------------------------------------------------------------------------ template <class T> dst_status DSt_cube<T>::writeToFile(char* output_prefix, dst_options options=0) { // Open file HANDLE file_handle = OpenOutputFile(output_prefix, options); if ( file_handle == INVALID_HANDLE_VALUE ) { return DST_FILE_IO_ERROR; } DWORD bytes_in_buffer; DWORD bytes_written; // If file caching is used, make a one slice buffer for copying back and forth // (I could not get the CopyFile() function to work) if ( cache_state ) { bytes_in_buffer = sizeof(T) * wX * wY; T *buffer = new T [wX * wY]; // Force a sync with file forceCacheSync(); // Make sure we are at start of cache file LARGE_INTEGER zero; zero.QuadPart = 0; SetFilePointerEx( cache_file, zero, NULL, FILE_BEGIN ); for (unsigned short z = 0; z < wZ; z++) { // Read in one slice from cache file ReadFile( cache_file, buffer, bytes_in_buffer, &bytes_written, NULL ); // Write it to requested file WriteFile( file_handle, buffer, bytes_in_buffer, &bytes_written, NULL ); } delete buffer; } else { bytes_in_buffer = sizeof(T) * wX * wY * slices_per_block; for (unsigned short i = 0; i < memory_num_of_blocks; i++) { if (i == (memory_num_of_blocks-1) ) { // Last block might have different number of slices bytes_in_buffer = sizeof(T) * wX * wY * slices_per_block_last; WriteFile( file_handle, memory_block_ptrs[i], bytes_in_buffer, &bytes_written, NULL ); } else { WriteFile( file_handle, memory_block_ptrs[i], bytes_in_buffer, &bytes_written, NULL ); } } } CloseHandle( file_handle ); return DST_NO_ERROR; }; //------------------------------------------------------------------------------------ // DSt_cube<T>::writeToFileRGB // Description - Writes cube to a file in RGB format, better looking but hard to know // true values. Color intensity is blue -> blue/green -> green -> green/red -> red -> red/blue //------------------------------------------------------------------------------------ template <class T> dst_status DSt_cube<T>::writeToFileRGB(char* output_prefix, T maxval/*=0*/, dst_options options, CProgressCtrl *progress_bar) { // Open file HANDLE file_handle = OpenOutputFile(output_prefix, options | DST_FILE_IS_RGB); if ( file_handle == INVALID_HANDLE_VALUE ) { return DST_FILE_IO_ERROR; } // Use a buffer the size of one RGB (24 bits per spot) slice to speed things up DWORD bytes_written; DWORD bytes_in_buffer = (DWORD) wX * wY * 3; unsigned char *rgb_buffer = new unsigned char[ bytes_in_buffer ]; int i = 0; unsigned short z, y, x; double ratio; // Setup progress bar, if provided if ( progress_bar ) { progress_bar->SetPos(0); progress_bar->SetStep(1); progress_bar->SetRange(0, wZ); } // If max_val is 0, need to search entire cube for max if ( maxval == 0 ) { FOR_wZwYwX_LOOP(this, z, y, x) { if ( datac(z, y, x) > maxval ) { maxval = datac(z, y, x); } } } for (z = 0; z < wZ; z++) { for (y = 0; y < wY; y++) { for (x = 0; x < wX; x++) { if ( datac(z, y, x) == 0 ) { // If 0, mark voxel as black rgb_buffer[i] = 0; rgb_buffer[i+1] = 0; rgb_buffer[i+2] = 0; } else if ( datac(z, y, x) > maxval ) { // If 'maxval', mark voxel as white rgb_buffer[i] = 255; rgb_buffer[i+1] = 255; rgb_buffer[i+2] = 255; } else { ratio = ( (double)datac(z, y, x) )/( maxval ); // Intensity trend: // blue -> blue/green -> green -> green/red -> red -> red/blue if (ratio < 1.0/6) { ratio = (ratio-0.0/6)*6; rgb_buffer[i] = (unsigned char) 40; rgb_buffer[i+1] = (unsigned char) 40; rgb_buffer[i+2] = (unsigned char)(40+ratio*(255-40)); } else if (ratio < 2.0/6) { ratio = (ratio-1.0/6)*6; rgb_buffer[i] = (unsigned char) 40; rgb_buffer[i+1] = (unsigned char)(40+ratio*(255-40)); rgb_buffer[i+2] = (unsigned char) 255; } else if (ratio < 3.0/6) { ratio = (ratio-2.0/6)*6; rgb_buffer[i] = (unsigned char) 40; rgb_buffer[i+1] = (unsigned char) 255; rgb_buffer[i+2] = (unsigned char)(255-ratio*(255-40)); } else if (ratio < 4.0/6) { ratio = (ratio-3.0/6)*6; rgb_buffer[i] = (unsigned char)(40+ratio*(255-40)); rgb_buffer[i+1] = (unsigned char) 255; rgb_buffer[i+2] = (unsigned char) 40; } else if (ratio < 5.0/6) { ratio = (ratio-4.0/6)*6; rgb_buffer[i] = (unsigned char) 255; rgb_buffer[i+1] = (unsigned char)(255-ratio*(255-40)); rgb_buffer[i+2] = (unsigned char) 40; } else { ratio = (ratio-5.0/6)*6; rgb_buffer[i] = (unsigned char) 255; rgb_buffer[i+1] = (unsigned char) 40; rgb_buffer[i+2] = (unsigned char)(40+ratio*(255-40)); } } i += 3; }//end FOR X }//end FOR Y // After every full slice, dump to file WriteFile( file_handle, rgb_buffer, bytes_in_buffer, &bytes_written, NULL ); i = 0; // Update progress if ( progress_bar ) { progress_bar->StepIt(); } }//end FOR Z CloseHandle( file_handle ); delete[] rgb_buffer; return DST_NO_ERROR; }; //------------------------------------------------------------------------------------ // DSt_cube<T>::readFromFile // Description - Reads a file into the cube, format assumed to be correct. //------------------------------------------------------------------------------------ template <class T> dst_status DSt_cube<T>::readFromFile(char *input_name, unsigned short start_at_files_z_index/*=0*/ ) { // Open file HANDLE file_handle = CreateFile( input_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL ); if( file_handle == INVALID_HANDLE_VALUE ) { write_to_log("DSt_cube<T>::readFromFile - Cannot open input file, %s", input_name); return DST_FILE_IO_ERROR; } LARGE_INTEGER start_offset_bytes; DWORD bytes_read; DWORD bytes_to_read = sizeof(T) * wX * wY * slices_per_block; // Seek to desired file offset start_offset_bytes.QuadPart = (LONGLONG) sizeof(T) * start_at_files_z_index * wX * wY; SetFilePointerEx( file_handle, start_offset_bytes, NULL, FILE_BEGIN ); // Read in data for (unsigned short i = 0; i < memory_num_of_blocks; i++) { if (i == (memory_num_of_blocks-1) ) { // Last block might have different number of slices bytes_to_read = sizeof(T) * wX * wY * slices_per_block_last; ReadFile( file_handle, memory_block_ptrs[i], bytes_to_read, &bytes_read, NULL ); } else { ReadFile( file_handle, memory_block_ptrs[i], bytes_to_read, &bytes_read, NULL ); } } CloseHandle( file_handle ); return DST_NO_ERROR; }; //--------------------------------(PRIVATE)------------------------------------------- // DSt_cube<T>::OpenOutputFile // Description - Appends cube dimensions and type to 'output_prefix' and opens // file for writing. //------------------------------------------------------------------------------------ template <class T> HANDLE DSt_cube<T>::OpenOutputFile(char* output_prefix, dst_options options=0) { if ( strlen(output_prefix) > MAX_FILE_STR_LEN-30 ) { write_to_log("DSt_cube<T>::writeToFile - Provided output prefix too long, %s", output_prefix); return NULL; } char file_name[MAX_FILE_STR_LEN]; if ( options & DST_DO_NOT_APPEND_SIZE ) { sprintf(file_name, "%s", output_prefix); } else { // If RGB specified, extension defaults to .u24.rgb if ( options&DST_FILE_IS_RGB ) { sprintf(file_name, "%s(%d_%d_%d).u24.rgb", output_prefix, wX, wY, wZ); } else { // Attempt to give appropriate extensions for signed/unsigned T test = (T)-1; if (test < 0) sprintf(file_name, "%s(%d_%d_%d).s%d.raw", output_prefix, wX, wY, wZ, sizeof(T)*8); else sprintf(file_name, "%s(%d_%d_%d).u%d.raw", output_prefix, wX, wY, wZ, sizeof(T)*8); } // Check if we need to update the file name if ( options & DST_UPDATE_FILE_NAME) { sprintf(output_prefix, "%s", file_name); } } // Create file HANDLE file_handle = CreateFile( file_name, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL ); if( file_handle == INVALID_HANDLE_VALUE ) { write_to_log("DSt_cube<T>::OpenOutputFile - Cannot open output file, %s", file_name); return NULL; } return file_handle; };