Go through all the selected images

 

The easiest way to go through all the selected images is to use the iterators.  Since the frame selection is window dependant, you need to know for what window you want to iterate.  Usually this is done for the current window.

 

// --- I need a pointer to the current window ---

SliceO_window *Cur_WIndow = (SliceO_Window *) Fct_Variable_Value( "$WINDOW_CUR" ) ;

if ( ! Cur_WIndow ) {

          // --- we have a problem here... get out! ---

          ...

}

 

// --- start an iterator ---

if ( Iterator_Init( ITERATOR_USER_1, "Name of this function" ) ) {

 

          // --- now go through all the selected frames ---

          while( SliceO_Frame *frame = (SliceO_Frame *) Iterator_Class( ITERATOR_USER_1, CLASS_TYPE_FRAME, Cur_Window, ITER_FLAG_SELECT ) ) {

 

                    // --- frame is now a pointer to one of the selected frames ---

                    ...

          }

 

           Iterator_End( ITERATOR_USER_1 ) ;

}

 

If you have lengthy computation to do on each frame, I would suggest to do it in separate threads to improve speed.  SliceO has a mechanism to help you with this, the "Fct_Dispatch_..." functions.

 

First, you need to create the "Struct_Dispatch_1" structure that will contain the list of the frames you want to perform the computation on, then you call the "Fct_Dispatch_..." with that structure.  There's 3 variation on the function depending on what your computation will affect (the TAG images, the GLI images, or something else).

 

 

int          Demo_Compute( void )

{

int          i=0 ;

void          *p_block = NULL ;

 

static          Struct_Dispatch_1 data ;

 

          memset( (void *) &data, NULL, sizeof(Struct_Dispatch_1) ) ;

 

          // --- I need a pointer to the current window ---

          data.window = (SliceO_Window *) Fct_Variable_Value( "$WINDOW_CUR" ) ;

          if ( ! data.window )

              return( 0 ) ;

 

          // --- how many images are selected/enabled ? ---

          unsigned int stack_size = 0 ;

          if ( Iterator_Init( ITERATOR_USER_1, "Demo_Compute" ) ) {

              while( SliceO_Frame *frame = (SliceO_Frame *) Iterator_Class( ITERATOR_USER_1, CLASS_ID_FRAME, data.window, ITER_FLAG_SELECT ) ) {

                    REALLOC( SliceO_Frame **, data.frame, data.nb_frame+1, sizeof(SliceO_Frame *) ) ;

                    data.frame[data.nb_frame++] = frame ;

              }

              Iterator_End( ITERATOR_USER_1 ) ;

          }

 

          // --- if no WS need to be computed, get out ---

          if ( ! data.nb_frame )

              return( 1 ) ;

 

          // --- we do not want this window to get under the others ---

          unsigned char *Interface_Lock_Focus = (unsigned char *) Fct_Variable_Get( "$INTERFACE_LOCK_FOCUS" ) ;

          if ( Interface_Lock_Focus )

              *Interface_Lock_Focus = 1 ;

 

          // --- open the progress report window (not if from a script!) ---

          if ( (data.nb_frame > 1) && ! (Script_Flag_Get() & SCRIPT_READ_LINE) )

              p_block = Progress_Init( hwnd, "Demo Progress", "Computing Demo" ) ;

          data.progress = p_block ;

 

          data.local_data = ... ;

          data.fct = Demo_Fct_Thread ;

 

          Error_Fct( hwnd, ERROR_CODE_REPORT, "Computing Watershed %d for \001%d\002 frames", merge+1, data.nb_frame ) ;

          Progress_Write( p_block, "Computing Watershed %d for \001%d\002 frames", merge+1, data.nb_frame ) ;

 

          Progress_Total( p_block, data.nb_frame ) ;

 

          HANDLE hThread = (HANDLE)_beginthreadex( NULL, 0, Fct_Dispatch_TAG, &data, 0, NULL ) ;

          if ( hThread == 0 ) {

              int err_no = GetLastError() ;

              Error_Fct( hwnd, ERROR_CODE_ERROR, "Unable to start thread\n %s", Error_Windows(err_no) ) ;

              Error_Fct( hwnd, ERROR_CODE_TRACE, "file:%s line:%d", __FILE__, __LINE__ ) ;

 

              FREE( data.frame ) ;

              Progress_End( p_block ) ;

              if ( Interface_Lock_Focus )

                    *Interface_Lock_Focus = 0 ;

              return( NULL ) ;

          }

 

          CloseHandle( hThread ) ;

 

          return( 1 ) ;

}

 

 

The "Fct_Dispatch_..." function will take care of dispatching 1 separate computation threads for each frame.  It will not start more thread than you have available CPUs.  You need to provide it with a pointer to your computation function (here the "Demo_Fct_thread") by placing the pointer to your computation function in the "data.fct" variable.  Your function will be called from each thread with a pointer to the "Struct_Dispatch_2" structure.  Your computation function must include a call to the "Fct_Dispatch_End" function

 

// ----------------------------------------------------------------------------

//

//          Func:    Demo_Fct_Thread()

//

// ----------------------------------------------------------------------------

static          unsigned __stdcall Demo_Fct_Thread( void *pvoid )

{

SliceO_Window *window =     ((Struct_Dispatch_2 *) pvoid)->window ;

SliceO_Frame *frame =              ((Struct_Dispatch_2 *) pvoid)->frame ;

void              *progress =              ((Struct_Dispatch_2 *) pvoid)->progress ;

 

          if ( Progress_Abort( progress ) )

              goto abort ;

 

          // --- if image is locked: skip ---

          if ( frame->Lock_Get() ) {

                    Error_Fct( hwnd, ERROR_CODE_WARNING, "\xF1\005WARNING:\002 image locked!" ) ;

                    Error_Fct( hwnd, ERROR_CODE_WARNING, "\xF1\t skipping: \001%s", frame->Name_Get() ) ;

                    Progress_Write( progress, "\xF1\005WARNING:\xF0\002 image locked!" ) ;

                    Progress_Write( progress, "\002   skipping: \001%s", frame->Name_Get() ) ;

                    goto exit ;

          }

 

          // --- Place a lock on this frame ---

          frame->Lock_Set( 1 ) ;

 

          // --- highlight the frame we are working on ---

          frame->Flag_Set_On( CLASS_MODE_THIS, window, CLASS_FLAG_HIGHLIGHT_BLU ) ;

          Fct_Redraw( REDRAW_HIGHLIGHT, window, frame ) ;

 

          // ====================================================================

          // ==================== Local processing ==============================

          // ====================================================================

 

                    Progress_Inc( progress, 1 ) ;

 

                    // --- Feedback to the user ---

                    if ( strlen(frame->Name_Get()) <= 30 )

                              Progress_Write( progress, "Compute Demo for \001%s", merge+1, frame->Name_Get() ) ;

                    else

                              Progress_Write( progress, "Compute Demo for \001%8.8s...%19.19s", merge+1,

                                        frame->Name_Get(), frame->Name_Get() + strlen(frame->Name_Get()) - 19 ) ;

 

                    ...

 

          

          // ====================================================================

          // ==================== Cleanup and get out ===========================

          // ====================================================================

exit:

 

          // --- unlock the GLI image ---

          frame->Lock_Set( -1 ) ;

 

abort:

 

          // --- reset the highlight ----

          // Note: this is done outside the critical region, it could be dangerous...

          frame->Flag_Set_Off( CLASS_MODE_THIS, window, CLASS_FLAG_HIGHLIGHT_BLU ) ;

          Fct_Redraw( REDRAW_HIGHLIGHT, window, frame ) ;

 

          // --- signal that we have finished ---

          Fct_Dispatch_End() ;

 

          _endthreadex( 1 ) ;

          return( 1 ) ;

}