void getInfo ( void *obj, info_t *info_ ) { VirtualVolume *volume = (VirtualVolume *) obj; std::string fmt = volume->getPrintableFormat(); info_->root_dir = volume->getROOT_DIR(); info_->VXL_V = volume->getVXL_V(); info_->VXL_H = volume->getVXL_H(); info_->VXL_D = volume->getVXL_D(); info_->ORG_V = volume->getORG_V(); info_->ORG_H = volume->getORG_H(); info_->ORG_D = volume->getORG_D(); info_->DIM_V = volume->getDIM_V(); info_->DIM_H = volume->getDIM_H(); info_->DIM_D = volume->getDIM_D(); info_->DIM_C = volume->getDIM_C(); info_->BYTESxCHAN = volume->getBYTESxCHAN(); info_->n_active = volume->getNACtiveChannels(); info_->active = volume->getActiveChannels(); info_->DIM_T = volume->getDIM_T(); info_->t0 = volume->getT0(); info_->t1 = volume->getT1(); }
//automatically called when current thread is started void CImport::run() { /**/itm::debug(itm::LEV1, 0, __itm__current__function__); try { timerIO.start(); /********************* 1) IMPORTING CURRENT VOLUME *********************** PRECONDITIONS: reimport = true ==> the volume cannot be directly imported (i.e., w/o the additional info provided by the user) or the user explicitly asked for re- importing the volume. reimport = false ==> the volume is directly importable *************************************************************************/ /**/itm::debug(itm::LEV_MAX, strprintf("importing current volume at \"%s\"", path.c_str()).c_str(), __itm__current__function__); // skip nonmatching entries QDir dir(path.c_str()); if( dir.dirName().toStdString().substr(0,3).compare(itm::RESOLUTION_PREFIX) != 0) throw RuntimeException(strprintf("\"%s\" is not a valid resolution: the name of the folder does not start with \"%s\"", path.c_str(), itm::RESOLUTION_PREFIX.c_str() ).c_str()); if(reimport) volumes.push_back(VirtualVolume::instance(path.c_str(), format, AXS_1, AXS_2, AXS_3, VXL_1, VXL_2, VXL_3)); else volumes.push_back(VirtualVolume::instance(path.c_str())); /********************* 2) IMPORTING OTHER VOLUMES *********************** Importing all the available resolutions within the current volume's parent directory. *************************************************************************/ /**/itm::debug(itm::LEV_MAX, "Importing other volumes of the multiresolution octree", __itm__current__function__); /* -------------------- detect candidate volumes -----------------------*/ /**/itm::debug(itm::LEV_MAX, "Detecting volumes that CAN be loaded (let us call them CANDIDATE volumes: the correspondent structures will be destroyed after this step)", __itm__current__function__); vector<VirtualVolume*> candidateVols; QDir curParentDir(path.c_str()); curParentDir.cdUp(); QStringList otherDirs = curParentDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); for(int k=0; k<otherDirs.size(); k++) { string path_i = curParentDir.absolutePath().append("/").append(otherDirs.at(k).toLocal8Bit().constData()).toStdString(); QDir dir_i(path_i.c_str()); // skip volumes[0] if(dir.dirName() == dir_i.dirName()) continue; // skip nonmatching entries if(dir_i.dirName().toStdString().substr(0,3).compare(itm::RESOLUTION_PREFIX) != 0) continue; /**/itm::debug(itm::LEV_MAX, strprintf("Checking for loadable volume at \"%s\"", path_i.c_str()).c_str(), __itm__current__function__); if( !reimport && VirtualVolume::isDirectlyImportable( path_i.c_str()) ) candidateVols.push_back(VirtualVolume::instance(path_i.c_str())); else volumes.push_back(VirtualVolume::instance(path_i.c_str(), volumes[0]->getPrintableFormat(), volumes[0]->getAXS_1(), volumes[0]->getAXS_2(), volumes[0]->getAXS_3(), volumes[0]->getVXL_1(), volumes[0]->getVXL_2(), volumes[0]->getVXL_3())); } /* -------------------- import candidate volumes ------------------------*/ /**/itm::debug(itm::LEV_MAX, "Importing loadable volumes (previously checked)", __itm__current__function__); for(int k=0; k<candidateVols.size(); k++) { int ratio = iim::round( pow((volumes[0]->getMVoxels() / candidateVols[k]->getMVoxels()),(1/3.0f)) ); /**/itm::debug(itm::LEV_MAX, strprintf("Importing loadable volume at \"%s\"", candidateVols[k]->getROOT_DIR()).c_str(), __itm__current__function__); if( !reimport && VirtualVolume::isDirectlyImportable( candidateVols[k]->getROOT_DIR()) ) volumes.push_back(VirtualVolume::instance(candidateVols[k]->getROOT_DIR())); else volumes.push_back(VirtualVolume::instance(candidateVols[k]->getROOT_DIR(), candidateVols[k]->getPrintableFormat(), volumes[0]->getAXS_1(), volumes[0]->getAXS_2(), volumes[0]->getAXS_3(), volumes[0]->getVXL_1()*ratio, volumes[0]->getVXL_2()*ratio, volumes[0]->getVXL_3()*ratio)); } /* -------------------- destroy candidate volumes -----------------------*/ /**/itm::debug(itm::LEV_MAX, "Destroying candidate volumes", __itm__current__function__); for(int k=0; k<candidateVols.size(); k++) delete candidateVols[k]; /* ------------- sort imported volumes by ascending size ---------------*/ /**/itm::debug(itm::LEV_MAX, "Sorting volumes by ascending size", __itm__current__function__); std::sort(volumes.begin(), volumes.end(), sortVolumesAscendingSize); /* ---------------------- check imported volumes -----------------------*/ if(volumes.size() < 2) throw RuntimeException(strprintf("%d resolution found at %s: at least two resolutions are needed for the multiresolution mode", volumes.size(), qPrintable(curParentDir.path()) ).c_str()); for(int k=0; k<volumes.size()-1; k++) { if(volumes[k]->getPrintableFormat().compare( volumes[k+1]->getPrintableFormat() ) != 0) throw RuntimeException(strprintf("Volumes have different formats at \"%s\"", qPrintable(curParentDir.absolutePath())).c_str()); if(volumes[k]->getDIM_T() != volumes[k+1]->getDIM_T()) throw RuntimeException(strprintf("Volumes have different time frames at \"%s\"", qPrintable(curParentDir.absolutePath())).c_str()); } /**************** 3) GENERATING / LOADING VOLUME 3D MAP ***************** We generate once for all a volume map from lowest-resolution volume. *************************************************************************/ string volMapPath = curParentDir.path().toStdString() + "/" + VMAP_BIN_FILE_NAME; if(hasVolumeMapToBeRegenerated(volMapPath.c_str(), "0.9.42", vmapTDimMax, volumes[0]->getDIM_T()) || reimport || regenerateVMap) { /**/itm::debug(itm::LEV_MAX, "Entering volume's map generation section", __itm__current__function__); // check that the lowest resolution does not exceed the maximum allowed size for the volume map VirtualVolume* lowestResVol = volumes[0]; if(lowestResVol->getDIM_H() > vmapXDimMax || lowestResVol->getDIM_V() > vmapYDimMax || lowestResVol->getDIM_D() > vmapZDimMax) itm::warning("@TODO: resample along XYZ so as to match the volume map maximum size", __itm__current__function__); vmapXDim = lowestResVol->getDIM_H(); vmapYDim = lowestResVol->getDIM_V(); vmapZDim = lowestResVol->getDIM_D(); vmapCDim = lowestResVol->getDIM_C(); // if the number of time frames exceeds the maximum, we put only the first vmapTDimMax in the volume map vmapTDim = std::min(vmapTDimMax, lowestResVol->getDIM_T()); // generate volume map lowestResVol->setActiveFrames(0, vmapTDimMax -1); vmapData = lowestResVol->loadSubvolume_to_UINT8(); FILE *volMapBin = fopen(volMapPath.c_str(), "wb"); if(!volMapBin) throw RuntimeException(strprintf("Cannot write volume map at \"%s\". Please check your write permissions.", volMapPath.c_str()).c_str()); uint16 verstr_size = static_cast<uint16>(strlen(itm::version.c_str()) + 1); fwrite(&verstr_size, sizeof(uint16), 1, volMapBin); fwrite(itm::version.c_str(), verstr_size, 1, volMapBin); fwrite(&vmapTDim, sizeof(uint32), 1, volMapBin); fwrite(&vmapCDim, sizeof(uint32), 1, volMapBin); fwrite(&vmapYDim, sizeof(uint32), 1, volMapBin); fwrite(&vmapXDim, sizeof(uint32), 1, volMapBin); fwrite(&vmapZDim, sizeof(uint32), 1, volMapBin); size_t vmapSize = ((size_t)vmapYDim)*vmapXDim*vmapZDim*vmapCDim*vmapTDim; fwrite(vmapData, vmapSize, 1, volMapBin); fclose(volMapBin); } else { /**/itm::debug(itm::LEV_MAX, "Entering volume's map loading section", __itm__current__function__); // load volume map FILE *volMapBin = fopen(volMapPath.c_str(), "rb"); uint16 verstr_size; if(!volMapBin) throw RuntimeException(strprintf("Cannot read volume map at \"%s\". Please check your read permissions.", volMapPath.c_str()).c_str()); if(!fread(&verstr_size, sizeof(uint16), 1, volMapBin)) throw RuntimeException("Unable to read volume map file (<version_size> field). Please delete the volume map and re-open the volume."); char ver[1024]; if(!fread(ver, verstr_size, 1, volMapBin)) throw RuntimeException("Unable to read volume map file (<version> field). Please delete the volume map and re-open the volume."); if(fread(&vmapTDim, sizeof(uint32), 1, volMapBin) != 1) throw RuntimeException("Unable to read volume map file (<vmapTDim> field). Please delete the volume map and re-open the volume."); if(fread(&vmapCDim, sizeof(uint32), 1, volMapBin) != 1) throw RuntimeException("Unable to read volume map file (<vmapCDim> field). Please delete the volume map and re-open the volume."); if(fread(&vmapYDim, sizeof(uint32), 1, volMapBin) != 1) throw RuntimeException("Unable to read volume map file (<vmapYDim> field). Please delete the volume map and re-open the volume."); if(fread(&vmapXDim, sizeof(uint32), 1, volMapBin)!= 1) throw RuntimeException("Unable to read volume map file (<vmapXDim> field). Please delete the volume map and re-open the volume."); if(fread(&vmapZDim, sizeof(uint32), 1, volMapBin)!= 1) throw RuntimeException("Unable to read volume map file (<vmapZDim> field). Please delete the volume map and re-open the volume."); size_t vmapSize = ((size_t)vmapYDim)*vmapXDim*vmapZDim*vmapCDim*vmapTDim; vmapData = new uint8[vmapSize]; if(fread(vmapData, vmapSize, 1, volMapBin) != 1) throw RuntimeException("Unable to read volume map file (<vmapData> field). Please delete the volume map and re-open the volume."); fclose(volMapBin); //--- Alessandro 29/09/2013: checking that the loaded vmap corresponds to one of the loaded volumes // /**/itm::debug(itm::LEV_MAX, "checking that the loaded vmap corresponds to one of the loaded volumes", __itm__current__function__); // bool check_passed = false; // for(int i=0; i<volumes.size() && !check_passed; i++) // if(volumes[i]->getDIM_V() == vmapYDim && // volumes[i]->getDIM_H() == vmapXDim && // volumes[i]->getDIM_D() == vmapZDim && // volumes[i]->getDIM_C() == vmapCDim) // check_passed = true; // if(!check_passed) // throw RuntimeException(QString("Volume map stored at \"").append(volMapPath.c_str()).append("\" does not correspond to any of the loaded resolutions. Please delete or regenerate the volume map.").toStdString().c_str()); } //everything went OK emit sendOperationOutcome(0, timerIO.elapsed()); /**/itm::debug(itm::LEV1, "EOF", __itm__current__function__); } catch( iim::IOException& exception) {reset(); emit sendOperationOutcome(new RuntimeException(exception.what()));} catch( iom::exception& exception) {reset(); emit sendOperationOutcome(new RuntimeException(exception.what()));} catch( RuntimeException& exception) {reset(); emit sendOperationOutcome(new RuntimeException(exception.what()));} catch(const char* error) {reset(); emit sendOperationOutcome(new RuntimeException(error));} catch(...) {reset(); emit sendOperationOutcome(new RuntimeException("Unknown error occurred"));} }
//automatically called when current thread is started void CVolume::run() { /**/tf::debug(tf::LEV1, 0, __itm__current__function__); try { VirtualVolume* volume = CImport::instance()->getVolume(voiResIndex); //---- Alessandro 2013-04-17: if VOI exceeds limits it is automatically adjusted. This is very useful in the cases the user is zooming-in //around peripheral regions voiV0 = voiV0 >=0 ? voiV0 : 0; voiV1 = voiV1 <= volume->getDIM_V() ? voiV1 : volume->getDIM_V(); voiH0 = voiH0 >=0 ? voiH0 : 0; voiH1 = voiH1 <= volume->getDIM_H() ? voiH1 : volume->getDIM_H(); voiD0 = voiD0 >=0 ? voiD0 : 0; voiD1 = voiD1 <= volume->getDIM_D() ? voiD1 : volume->getDIM_D(); // voiT0 = voiT0 >=0 ? voiT0 : 0; // voiT1 = voiT1 < volume->getDIM_T() ? voiT1 : volume->getDIM_T()-1; // check subvolume interval if(voiV1 - voiV0 <=0 || voiH1 - voiH0 <=0 || voiD1 - voiD0 <=0 || voiT1 - voiT0 <0) throw RuntimeException(strprintf("Invalid subvolume intervals inserted: X=[%d, %d), Y=[%d, %d), Z=[%d, %d), T=[%d, %d]", voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiT0, voiT1)); // check destination /**/tf::debug(tf::LEV2, "Check destination", __itm__current__function__); CViewer* destination = dynamic_cast<CViewer*>(source); if(!destination) throw RuntimeException("Destination type not supported"); /**/tf::debug(tf::LEV2, strprintf("destination registered as \"%s\"", destination->title.c_str()).c_str(), __itm__current__function__); //checking for an imported volume if(volume) { if(streamingSteps == 1) { // 5D data with instant visualization of selected frame if(voiT0 != voiT1 && cur_t != -1) { // load selected frame QElapsedTimer timerIO; timerIO.start(); volume->setActiveFrames(cur_t, cur_t); /**/tf::debug(tf::LEV3, "load selected time frame", __itm__current__function__); uint8* voiData = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1); qint64 elapsedTime = timerIO.elapsed(); // wait for GUI thread to update graphics /**/tf::debug(tf::LEV3, "Waiting for updateGraphicsInProgress mutex", __itm__current__function__); /**/ updateGraphicsInProgress.lock(); /**/tf::debug(tf::LEV3, "Access granted from updateGraphicsInProgress mutex", __itm__current__function__); // send data integer_array data_s = make_vector<int>() << voiH0 << voiV0 << voiD0 << 0 << cur_t; integer_array data_c = make_vector<int>() << voiH1-voiH0 << voiV1-voiV0 << voiD1-voiD0 << volume->getNACtiveChannels() << 1; emit sendData(voiData, data_s, data_c, source, false, 0, elapsedTime, strprintf("Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d), T=[%d, %d] loaded from res %d", voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, cur_t, cur_t, voiResIndex).c_str()); // unlock updateGraphicsInProgress mutex /**/tf::debug(tf::LEV3, strprintf("updateGraphicsInProgress.unlock()").c_str(), __itm__current__function__); /**/ updateGraphicsInProgress.unlock(); } { // load data QElapsedTimer timerIO; timerIO.start(); volume->setActiveFrames(voiT0, voiT1); /**/tf::debug(tf::LEV3, "load data", __itm__current__function__); uint8* voiData = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1); qint64 elapsedTime = timerIO.elapsed(); // wait for GUI thread to update graphics /**/tf::debug(tf::LEV3, "Waiting for updateGraphicsInProgress mutex", __itm__current__function__); /**/ updateGraphicsInProgress.lock(); /**/tf::debug(tf::LEV3, "Access granted from updateGraphicsInProgress mutex", __itm__current__function__); // send data integer_array data_s = make_vector<int>() << voiH0 << voiV0 << voiD0 << 0 << voiT0; integer_array data_c = make_vector<int>() << voiH1-voiH0 << voiV1-voiV0 << voiD1-voiD0 << volume->getNACtiveChannels() << voiT1-voiT0+1; emit sendData(voiData, data_s, data_c, source, true, 0, elapsedTime, strprintf("Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d), T=[%d, %d] loaded from res %d", voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiT0, voiT1, voiResIndex).c_str()); /**/tf::debug(tf::LEV3, "sendData signal emitted", __itm__current__function__); // unlock updateGraphicsInProgress mutex /**/tf::debug(tf::LEV3, strprintf("updateGraphicsInProgress.unlock()").c_str(), __itm__current__function__); /**/ updateGraphicsInProgress.unlock(); } } else { throw RuntimeException("Streaming != 1 has been temporarily disabled. Please contact the developer."); // // precondition checks // if(!buffer) // throw RuntimeException("Buffer not initialized"); // CViewer* destination = dynamic_cast<CViewer*>(source); // if(!destination) // throw RuntimeException("Streaming not yet supported for this type of destination"); // if(streamingSteps != 2) // throw RuntimeException("Only streaming steps = 2 supported for 5D data"); // for (int step = 1; step <= streamingSteps; step++) // { // // load current selected frame // /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: loading data", step).c_str(), __itm__current__function__); // volume->setActiveFrames(step == 1 ? cur_t : voiT0, step == 1 ? cur_t : voiT1); // QElapsedTimer timerIO; // timerIO.start(); // uint8* data = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1); // qint64 elapsedTime = timerIO.elapsed(); // // copy frame to buffer ( ** CRITICAL SECTION ** ) // /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: waiting for buffer mutex", step).c_str(), __itm__current__function__); // /**/ bufferMutex.lock(); // /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: access granted on buffer mutex", step).c_str(), __itm__current__function__); // uint32 buf_dims[5] = {voiH1-voiH0, voiV1-voiV0, voiD1-voiD0, volume->getDIM_C(), voiT1 - voiT0 +1}; // uint32 buf_offset[5] = {0, 0, 0, 0, cur_t-voiT0}; // uint32 cur_t_dims[5] = {voiH1-voiH0, voiV1-voiV0, voiD1-voiD0, volume->getDIM_C(), 1}; // uint32 cur_t_offset[5] = {0, 0, 0, 0, 0}; // uint32 cur_t_count[5] = {voiH1-voiH0, voiV1-voiV0, voiD1-voiD0, volume->getDIM_C(), 1}; // CViewer::copyVOI(cur_t_data, cur_t_dims, cur_t_offset, cur_t_count, buffer, buf_dims, buf_offset); // delete[] cur_t_data; // /**/ bufferMutex.unlock(); // /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: unlocked buffer mutex", step).c_str(), __itm__current__function__); // // wait GUI thread to complete update graphics // /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: waiting for updateGraphicsInProgress mutex", step).c_str(), __itm__current__function__); // /**/ destination->updateGraphicsInProgress.lock(); // /**/ destination->updateGraphicsInProgress.unlock(); // /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: unlocked updateGraphicsInProgress mutex", step).c_str(), __itm__current__function__); // // send data to GUI thread // finished = false; // /**/tf::debug(tf::LEV3, strprintf("Time step %d/2: sendOperationOutcome", step).c_str(), __itm__current__function__); // sprintf(msg, "Streaming %d/%d: Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d) loaded from res %d", // 1, 2, voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiResIndex); // emit sendOperationOutcome(buffer, 0, destination, elapsedTime, msg, 1); // } // // load current selected frame // /**/tf::debug(tf::LEV3, "Time step 1/2: loading data", __itm__current__function__); // volume->setActiveFrames(cur_t, cur_t); // QElapsedTimer timerIO; // timerIO.start(); // uint8* cur_t_data = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1); // qint64 elapsedTime = timerIO.elapsed(); // /**/tf::debug(tf::LEV3, "Time step 2/2: waiting for buffer mutex", __itm__current__function__); // /**/ bufferMutex.lock(); // /**/tf::debug(tf::LEV3, "Time step 2/2: access granted on buffer mutex", __itm__current__function__); // timerIO.start(); // volume->setActiveFrames(voiT0 + (voiT1-voiT0)/2, voiT1); // /**/tf::debug(tf::LEV3, "Time step 2/2: loading data", __itm__current__function__); // buffer = volume->loadSubvolume_to_UINT8(voiV0, voiV1, voiH0, voiH1, voiD0, voiD1); // elapsedTime = timerIO.elapsed(); // /**/ bufferMutex.unlock(); // /**/tf::debug(tf::LEV3, "Time step 2/2: unlocked buffer mutex", __itm__current__function__); // sprintf(msg, "Streaming %d/%d: Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d) loaded from res %d", // 2, 2, voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiResIndex); // /**/tf::debug(tf::LEV3, "Time step 1/2: waiting for updateGraphicsInProgress mutex", __itm__current__function__); // /**/ destination->updateGraphicsInProgress.lock(); // /**/ destination->updateGraphicsInProgress.unlock(); // /**/tf::debug(tf::LEV3, "Time step 1/2: unlocked updateGraphicsInProgress mutex", __itm__current__function__); // finished = true; // /**/tf::debug(tf::LEV3, "Time step 1/2: sendOperationOutcome", __itm__current__function__); // emit sendOperationOutcome(buffer, 0, destination, elapsedTime, msg, 2); // //checking preconditions // TiledVolume* vaa3D_volume_RGB = dynamic_cast<TiledVolume*>(volume); // TiledMCVolume* vaa3D_volume_4D= dynamic_cast<TiledMCVolume*>(volume); // if(!vaa3D_volume_RGB && !vaa3D_volume_4D) // throw RuntimeException("Streaming not yet supported for the current format. Please restart the plugin."); // if(!buffer) // throw RuntimeException("Buffer not initialized"); // CViewer* destination = dynamic_cast<CViewer*>(source); // if(!destination) // throw RuntimeException("Streaming not yet supported for this type of destination"); // //reading/writing from/to the same buffer with MUTEX (see Producer-Consumer problem) // /**/tf::debug(tf::LEV3, "Calling streamedLoadSubvolume_open", __itm__current__function__); // void *stream_descr = 0; // if(vaa3D_volume_RGB) // stream_descr = vaa3D_volume_RGB->streamedLoadSubvolume_open(streamingSteps, buffer, voiV0, voiV1, voiH0, voiH1, voiD0, voiD1); // else // stream_descr = vaa3D_volume_4D->streamedLoadSubvolume_open(streamingSteps, buffer, voiV0, voiV1, voiH0, voiH1, voiD0, voiD1); // for (int currentStep = 1; currentStep <= streamingSteps; currentStep++) // { // /**/tf::debug(tf::LEV3, "Waiting for buffer mutex", __itm__current__function__); // /**/ bufferMutex.lock(); // /**/tf::debug(tf::LEV3, "Access granted to buffer mutex, locking", __itm__current__function__); // QElapsedTimer timerIO; // timerIO.start(); // if(vaa3D_volume_RGB) // buffer = vaa3D_volume_RGB->streamedLoadSubvolume_dostep(stream_descr); // else if(vaa3D_volume_4D) // buffer = vaa3D_volume_4D->streamedLoadSubvolume_dostep(stream_descr); // qint64 elapsedTime = timerIO.elapsed(); // /**/ bufferMutex.unlock(); // /**/tf::debug(tf::LEV3, "Unlocked buffer mutex", __itm__current__function__); // sprintf(msg, "Streaming %d/%d: Block X=[%d, %d) Y=[%d, %d) Z=[%d, %d) loaded from res %d", // currentStep, streamingSteps, voiH0, voiH1, voiV0, voiV1, voiD0, voiD1, voiResIndex); // /**/tf::debug(tf::LEV3, "Waiting for updateGraphicsInProgress mutex", __itm__current__function__); // /**/ destination->updateGraphicsInProgress.lock(); // /**/ destination->updateGraphicsInProgress.unlock(); // /**/tf::debug(tf::LEV3, "Unlocked updateGraphicsInProgress mutex", __itm__current__function__); // finished = currentStep == streamingSteps; // if(finished) // { // /**/tf::debug(tf::LEV3, "Calling streamedLoadSubvolume_close", __itm__current__function__); // if(vaa3D_volume_RGB) // buffer = vaa3D_volume_RGB->streamedLoadSubvolume_close(stream_descr); // else if(vaa3D_volume_4D) // buffer = vaa3D_volume_4D->streamedLoadSubvolume_close(stream_descr); // } // /**/tf::debug(tf::LEV3, strprintf("sendOperationOutcome, step %d", currentStep).c_str(), __itm__current__function__); // emit sendOperationOutcome(buffer, 0, destination, elapsedTime, msg, currentStep); } } else throw RuntimeException("No volume has been imported yet."); /**/tf::debug(tf::LEV1, "EOF", __itm__current__function__); } catch( iim::IOException& exception) { // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex CViewer* dest = dynamic_cast<CViewer*>(source); /**/ updateGraphicsInProgress.lock(); reset(); //bufferMutex.unlock(); tf::warning(exception.what(), "CVolume"); /**/ updateGraphicsInProgress.unlock(); emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException(exception.what()), 0, ""); } catch( iom::exception& exception) { // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex CViewer* dest = dynamic_cast<CViewer*>(source); /**/ updateGraphicsInProgress.lock(); reset(); //bufferMutex.unlock(); tf::warning(exception.what(), "CVolume"); /**/ updateGraphicsInProgress.unlock(); emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException(exception.what()), 0, ""); } catch( RuntimeException& exception) { // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex CViewer* dest = dynamic_cast<CViewer*>(source); /**/ updateGraphicsInProgress.lock(); reset(); //bufferMutex.unlock(); tf::warning(exception.what(), "CVolume"); /**/ updateGraphicsInProgress.unlock(); emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException(exception.what()), 0, ""); } catch(const char* error) { // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex CViewer* dest = dynamic_cast<CViewer*>(source); /**/ updateGraphicsInProgress.lock(); reset(); //bufferMutex.unlock(); tf::warning(error, "CVolume"); /**/ updateGraphicsInProgress.unlock(); emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException(error), 0, ""); } catch(...) { // before emit signal, it is necessary to wait for updateGraphicsInProgress mutex CViewer* dest = dynamic_cast<CViewer*>(source); /**/ updateGraphicsInProgress.lock(); reset(); //bufferMutex.unlock(); tf::warning("Unknown error occurred", "CVolume"); /**/ updateGraphicsInProgress.unlock(); emit sendData(0, make_vector<int>(), make_vector<int>(), dest, true, new RuntimeException("Unknown error occurred"), 0, ""); } }