void
RemapImage::wheelEvent(QWheelEvent *event)
{
  int minS, maxS;
  if (m_sliceType == DSlice)
    { 
      minS = m_minDSlice; 
      maxS = m_maxDSlice; 
    } 
  else if (m_sliceType == WSlice) 
    { 
      minS = m_minWSlice; 
      maxS = m_maxWSlice; 
    } 
  else 
    { 
      minS = m_minHSlice; 
      maxS = m_maxHSlice; 
    }  

  int numSteps = event->delta()/8.0f/15.0f;
  m_currSlice -= numSteps;
  m_currSlice = qBound(minS, m_currSlice, maxS);
  emit getSlice(m_currSlice);
  update();
}
Exemple #2
0
  /**
   * Get the average image at the given altitude.
   * If the altitude is not located exactly at one of the altitude bins,
   * the average image is interpolated between any overlapping bins.
   * @param _dst the output image (zeros at desired resolution)
   * @param alt the altitude the image was taken at
   * @param pitch the pitch of the vehicle
   * @param roll the roll of the vehicle
   */
  void getAverage(cv::OutputArray _dst, double alt, double pitch, double roll) {
    Mat dst = _dst.getMat();
    int width = dst.size().width;
    int height = dst.size().height;
    Mat D = Mat::zeros(height, width, CV_32F);
    double width_m = width * cameras.pixel_sep;
    double height_m = height * cameras.pixel_sep;
    interp::distance_map(D, alt, pitch, roll, width_m, height_m, cameras.focal_length);
    // now discretize into slices
    int i = 0;
    Mat W = Mat::zeros(D.size(), CV_32F);
    while(cv::countNonZero(W) == 0) {
      interp::dist_weight(D, W, alt_step, i++);
    }
    while(cv::countNonZero(W) > 0) {
      Slice<int>* slice = getSlice(i);
      Mat sAverage;
      // get the slice average
      boost::mutex* mutex = slice->get_mutex();
      { // protect slice with mutex to prevent interleaved read/write operations
	boost::lock_guard<boost::mutex> lock(*mutex);
	sAverage = slice->getLightfield()->getAverage();
      }
      dst += sAverage.mul(W); // multiply by slice weight
      interp::dist_weight(D, W, alt_step, i++);
    }
  }
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void SobelEdge::readFilterParameters(AbstractFilterParametersReader* reader, int index)
{
  reader->openFilterGroup(this, index);
  setSelectedCellArrayPath( reader->readDataArrayPath( "SelectedCellArrayPath", getSelectedCellArrayPath() ) );
  setNewCellArrayName( reader->readString( "NewCellArrayName", getNewCellArrayName() ) );
  setSaveAsNewArray( reader->readValue( "SaveAsNewArray", getSaveAsNewArray() ) );
  setSlice( reader->readValue( "Slice", getSlice() ) );
  reader->closeFilterGroup();
}
void VolumeDisplayUnit::setSlabThickness(int thickness)
{
    // Make sure thickness is within valid bounds. Must be between 1 and the maximum number of slices on the curren view.
    int admittedThickness = qBound(1, thickness, getNumberOfSlices());
    
    m_sliceHandler->setSlabThickness(admittedThickness);
    m_imagePipeline->setSlice(m_volume->getImageIndex(getSlice(), getPhase()));
    m_imagePipeline->setSlabThickness(admittedThickness);
}
Exemple #5
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void Threshold::readFilterParameters(AbstractFilterParametersReader* reader, int index)
{
  reader->openFilterGroup(this, index);
  setSelectedCellArrayName( reader->readValue( "SelectedCellArrayName", getSelectedCellArrayName() ) );
  setNewCellArrayName( reader->readValue( "NewCellArrayName", getNewCellArrayName() ) );
  setOverwriteArray( reader->readValue( "OverwriteArray", getOverwriteArray() ) );
  setSlice( reader->readValue( "Slice", getSlice() ) );
  setManualParameter( reader->readValue( "ManualParameter", getManualParameter() ) );
  reader->closeFilterGroup();
}
Exemple #6
0
void Sprite::updateAnim()
{
    // Is animation set
    if (m_Animation != NULL)
    {
        // Update, but only change frame if current frame is updated
        if (m_Animation->update())
            getSlice(m_Animation->getCurrentFrame());
    }
}
Exemple #7
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
int Threshold::writeFilterParameters(AbstractFilterParametersWriter* writer, int index)

{
  writer->openFilterGroup(this, index);
  writer->writeValue("SelectedCellArrayName", getSelectedCellArrayName() );
  writer->writeValue("NewCellArrayName", getNewCellArrayName() );
  writer->writeValue("OverwriteArray", getOverwriteArray() );
  writer->writeValue("Slice", getSlice() );
  writer->writeValue("ManualParameter", getManualParameter() );
  writer->closeFilterGroup();
  return ++index;
}
void
RemapImage::sliceChanged(int slc)
{
  if (m_sliceType == DSlice)
    m_currDSlice = m_currSlice = slc;
  else if (m_sliceType == WSlice)
    m_currWSlice = m_currSlice = slc;
  else
    m_currHSlice = m_currSlice = slc;

  //emit getSliceLowres(m_currSlice);
  emit getSlice(m_currSlice);
}
double VolumeDisplayUnit::getCurrentDisplayedImageDepth() const
{
    if (getVolume())
    {
        double zSpacing = getCurrentSpacingBetweenSlices();
        int zIndex = getViewPlane().getZIndex();
        double zOrigin = getVolume()->getOrigin()[zIndex];
        
        return zOrigin + zSpacing * getSlice();
    }
    else
    {
        return 0.0;
    }
}
Exemple #10
0
  /**
   * Add an image to the lightfield
   * @param image the image to add
   * @param alt the altitude the image was taken at
   * @param pitch the pitch of the vehicle
   * @param roll the roll of the vehicle
   */
  int addImage(Mat image, double alt, double pitch, double roll) {
    // compute distance map
    int width = image.size().width;
    int height = image.size().height;
    Mat D = Mat::zeros(height, width, CV_32F);
    double width_m = width * cameras.pixel_sep;
    double height_m = height * cameras.pixel_sep;
    if(false) { // FIXME unfinished
      Mat left = Mat(D,cv::Rect(0,0,width/2,height));
      Mat right = Mat(D,cv::Rect(width/2,0,width/2,height));
      // now compute center of overlap region in sensor coordinates
      double xoff_m = cameras.alt2xoff(alt) * cameras.pixel_sep;
      // compute distance map for each camera frame centered on the center of the overlap region
      double cx_L = 0; // FIXME do something here
      double cx_R = 0; // FIXME do something here
      interp::distance_map(left, alt, pitch, roll, width_m/2, height_m, cameras.focal_length, cx_L);
      interp::distance_map(right, alt, pitch, roll, width_m/2, height_m, cameras.focal_length, cx_R);
    } else {
      // for now, compute a distance map that in the case of stereo pairs spans the whole image
      interp::distance_map(D, alt, pitch, roll, width_m, height_m, cameras.focal_length);
    }
    // now discretize into slices
    int i = 0;
    Mat W = Mat::zeros(D.size(), CV_32F);
    while(cv::countNonZero(W) == 0) {
      interp::dist_weight(D, W, alt_step, i++);
    }
    while(cv::countNonZero(W) > 0) {
      Slice<int>* slice = getSlice(i);
      boost::mutex* mutex = slice->get_mutex();
      { // protect slice with mutex to prevent concurrent writes
	boost::lock_guard<boost::mutex> lock(*mutex);
	slice->getLightfield()->addImage(image, W);
      }
      interp::dist_weight(D, W, alt_step, i++);
    }
    return 0;
  }
void VolumeDisplayUnit::setPhase(int phase)
{
    m_sliceHandler->setPhase(phase);
    m_imagePipeline->setSlice(m_volume->getImageIndex(getSlice(), getPhase()));
}
void
RemapImage::setSliceType(int st)
{
  m_sliceType = st;
  if (m_sliceType == DSlice)
    m_currSlice = qBound(m_minDSlice, m_currDSlice, m_maxDSlice);
  else if (m_sliceType == WSlice)
    m_currSlice = qBound(m_minWSlice, m_currWSlice, m_maxWSlice);
  else
    m_currSlice = qBound(m_minHSlice, m_currHSlice, m_maxHSlice);

  //---------------------------------
  // update rubberband extents
  float left, right, top, bottom;

  float width, height;
  if (m_sliceType == DSlice)
    {
      left = (float)m_minHSlice/(float)m_Height;
      right = (float)m_maxHSlice/(float)m_Height;
      top = (float)m_minWSlice/(float)m_Width;
      bottom = (float)m_maxWSlice/(float)m_Width;

      width = m_Height;
      height = m_Width;
    }
  else if (m_sliceType == WSlice)
    {
      left = (float)m_minHSlice/(float)m_Height;
      right = (float)m_maxHSlice/(float)m_Height;
      top = (float)m_minDSlice/(float)m_Depth;
      bottom = (float)m_maxDSlice/(float)m_Depth;

      width = m_Height;
      height = m_Depth;
    }
  else
    {
      left = (float)m_minWSlice/(float)m_Width;
      right = (float)m_maxWSlice/(float)m_Width;
      top = (float)m_minDSlice/(float)m_Depth;
      bottom = (float)m_maxDSlice/(float)m_Depth;

      width = m_Width;
      height = m_Depth;
    }

  left = qBound(0.0f, left, 1.0f);
  top = qBound(0.0f, top, 1.0f);
  right = qBound(0.0f, right, 1.0f);
  bottom = qBound(0.0f, bottom, 1.0f);

  m_rubberBand.setLeft(left);
  m_rubberBand.setTop(top);
  m_rubberBand.setRight(right);
  m_rubberBand.setBottom(bottom);
  //---------------------------------


  // reset zoom
  QWidget *prt = (QWidget*)parent();
  int frmHeight = prt->rect().height()-50;
  int frmWidth = prt->rect().width()-50;
  float rH = (float)frmHeight/(float)height;
  float rW = (float)frmWidth/(float)width;
  if (m_zoom < 0.01)
    m_zoom = qMin(rH, rW);
  
  emit getSliceLowres(m_currSlice);
  emit getSlice(m_currSlice);

  updateStatusText();
}
Exemple #13
0
Sprite* Sprite::getSlice(int x, int y)
{
    int cols = m_Texture->getWidth() / m_SubWidth;
    return getSlice(x + y * cols);
}
Exemple #14
0
/** Create non-deblocked filter information
 * \param pSliceStartAddress array for storing slice start addresses
 * \param numSlices number of slices in picture
 * \param sliceGranularityDepth slice granularity 
 * \param bNDBFilterCrossSliceBoundary cross-slice-boundary in-loop filtering; true for "cross".
 * \param numTiles number of tiles in picture
 * \param bNDBFilterCrossTileBoundary cross-tile-boundary in-loop filtering; true for "cross".
 */
Void TComPic::createNonDBFilterInfo(std::vector<Int> sliceStartAddress, Int sliceGranularityDepth
                                    ,std::vector<Bool>* LFCrossSliceBoundary
                                    ,Int numTiles
                                    ,Bool bNDBFilterCrossTileBoundary)
{
  UInt maxNumSUInLCU = getNumPartInCU();
  UInt numLCUInPic   = getNumCUsInFrame();
  UInt picWidth      = getSlice(0)->getSPS()->getPicWidthInLumaSamples();
  UInt picHeight     = getSlice(0)->getSPS()->getPicHeightInLumaSamples();
  Int  numLCUsInPicWidth = getFrameWidthInCU();
  Int  numLCUsInPicHeight= getFrameHeightInCU();
  UInt maxNumSUInLCUWidth = getNumPartInWidth();
  UInt maxNumSUInLCUHeight= getNumPartInHeight();
  Int  numSlices = (Int) sliceStartAddress.size() - 1;
  m_bIndependentSliceBoundaryForNDBFilter = false;
  if(numSlices > 1)
  {
    for(Int s=0; s< numSlices; s++)
    {
      if((*LFCrossSliceBoundary)[s] == false)
      {
        m_bIndependentSliceBoundaryForNDBFilter = true;
      }
    }
  }
  m_sliceGranularityForNDBFilter = sliceGranularityDepth;
  m_bIndependentTileBoundaryForNDBFilter  = (bNDBFilterCrossTileBoundary)?(false) :((numTiles > 1)?(true):(false));

  m_pbValidSlice = new Bool[numSlices];
  for(Int s=0; s< numSlices; s++)
  {
    m_pbValidSlice[s] = true;
  }
  m_pSliceSUMap = new Int[maxNumSUInLCU * numLCUInPic];

  //initialization
  for(UInt i=0; i< (maxNumSUInLCU * numLCUInPic); i++ )
  {
    m_pSliceSUMap[i] = -1;
  }
  for( UInt CUAddr = 0; CUAddr < numLCUInPic ; CUAddr++ )
  {
    TComDataCU* pcCU = getCU( CUAddr );
    pcCU->setSliceSUMap(m_pSliceSUMap + (CUAddr* maxNumSUInLCU)); 
    pcCU->getNDBFilterBlocks()->clear();
  }
  m_vSliceCUDataLink.clear();

  m_vSliceCUDataLink.resize(numSlices);

  UInt startAddr, endAddr, firstCUInStartLCU, startLCU, endLCU, lastCUInEndLCU, uiAddr;
  UInt LPelX, TPelY, LCUX, LCUY;
  UInt currSU;
  UInt startSU, endSU;

  for(Int s=0; s< numSlices; s++)
  {
    //1st step: decide the real start address
    startAddr = sliceStartAddress[s];
    endAddr   = sliceStartAddress[s+1] -1;

    startLCU            = startAddr / maxNumSUInLCU;
    firstCUInStartLCU   = startAddr % maxNumSUInLCU;

    endLCU              = endAddr   / maxNumSUInLCU;
    lastCUInEndLCU      = endAddr   % maxNumSUInLCU;   

    uiAddr = m_apcPicSym->getCUOrderMap(startLCU);

    LCUX      = getCU(uiAddr)->getCUPelX();
    LCUY      = getCU(uiAddr)->getCUPelY();
    LPelX     = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[firstCUInStartLCU] ];
    TPelY     = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[firstCUInStartLCU] ];
    currSU    = firstCUInStartLCU;

    Bool bMoveToNextLCU = false;
    Bool bSliceInOneLCU = (startLCU == endLCU);

    while(!( LPelX < picWidth ) || !( TPelY < picHeight ))
    {
      currSU ++;

      if(bSliceInOneLCU)
      {
        if(currSU > lastCUInEndLCU)
        {
          m_pbValidSlice[s] = false;
          break;
        }
      }

      if(currSU >= maxNumSUInLCU )
      {
        bMoveToNextLCU = true;
        break;
      }

      LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
      TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];

    }


    if(!m_pbValidSlice[s])
    {
      continue;
    }

    if(currSU != firstCUInStartLCU)
    {
      if(!bMoveToNextLCU)
      {
        firstCUInStartLCU = currSU;
      }
      else
      {
        startLCU++;
        firstCUInStartLCU = 0;
        assert( startLCU < getNumCUsInFrame());
      }
      assert(startLCU*maxNumSUInLCU + firstCUInStartLCU < endAddr);
    }


    //2nd step: assign NonDBFilterInfo to each processing block
    for(UInt i= startLCU; i <= endLCU; i++)
    {
      startSU = (i == startLCU)?(firstCUInStartLCU):(0);
      endSU   = (i == endLCU  )?(lastCUInEndLCU   ):(maxNumSUInLCU -1);

      uiAddr = m_apcPicSym->getCUOrderMap(i);
      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);

      TComDataCU* pcCU = getCU(uiAddr);
      m_vSliceCUDataLink[s].push_back(pcCU);

      createNonDBFilterInfoLCU(iTileID, s, pcCU, startSU, endSU, m_sliceGranularityForNDBFilter, picWidth, picHeight);
    }
  }

  //step 3: border availability
  for(Int s=0; s< numSlices; s++)
  {
    if(!m_pbValidSlice[s])
    {
      continue;
    }

    for(Int i=0; i< m_vSliceCUDataLink[s].size(); i++)
    {
      TComDataCU* pcCU = m_vSliceCUDataLink[s][i];
      uiAddr = pcCU->getAddr();

      if(pcCU->getPic()==0)
      {
        continue;
      }
      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
      Bool bTopTileBoundary = false, bDownTileBoundary= false, bLeftTileBoundary= false, bRightTileBoundary= false;

      if(m_bIndependentTileBoundaryForNDBFilter)
      {
        //left
        if( uiAddr % numLCUsInPicWidth != 0)
        {
          bLeftTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr -1) != iTileID )?true:false;
        }
        //right
        if( (uiAddr % numLCUsInPicWidth) != (numLCUsInPicWidth -1) )
        {
          bRightTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr +1) != iTileID)?true:false;
        }
        //top
        if( uiAddr >= numLCUsInPicWidth)
        {
          bTopTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr - numLCUsInPicWidth) !=  iTileID )?true:false;
        }
        //down
        if( uiAddr + numLCUsInPicWidth < numLCUInPic )
        {
          bDownTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr + numLCUsInPicWidth) != iTileID)?true:false;
        }

      }

      pcCU->setNDBFilterBlockBorderAvailability(numLCUsInPicWidth, numLCUsInPicHeight, maxNumSUInLCUWidth, maxNumSUInLCUHeight,picWidth, picHeight
        , *LFCrossSliceBoundary
        ,bTopTileBoundary, bDownTileBoundary, bLeftTileBoundary, bRightTileBoundary
        ,m_bIndependentTileBoundaryForNDBFilter);

    }

  }

  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
  {
    m_pNDBFilterYuvTmp = new TComPicYuv();
    m_pNDBFilterYuvTmp->create(picWidth, picHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
  }

}
Exemple #15
0
Void TDecEntropy::decodePLTModeInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool& bCodeDQP, Bool& isChromaQpAdjCoded )
{
  // Note: the condition is log2CbSize < MaxTbLog2SizeY in 7.3.8.5 of JCTVC-T1005-v2
  if( pcCU->getSlice()->getSPS()->getSpsScreenExtension().getUsePLTMode() && pcCU->isIntra( uiAbsPartIdx ) && (pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth) < 64 )
  {
    m_pcEntropyDecoderIf->parsePLTModeFlag( pcCU, uiAbsPartIdx, uiDepth );
    if ( pcCU->getPLTModeFlag( uiAbsPartIdx ) )
    {
      m_pcEntropyDecoderIf->parsePLTModeSyntax( pcCU, uiAbsPartIdx, uiDepth, 3, bCodeDQP, isChromaQpAdjCoded );
      pcCU->saveLastPLTInLcuFinal( pcCU, uiAbsPartIdx, MAX_NUM_COMPONENT );
    }
  }
}
Exemple #16
0
// extern __thread jmp_buf jumpBuf;
int VM::call(Value A, int nEffArgs, Value *regs, Stack *stack) {
    Vector<RetInfo> retInfo; // only used if FAST_CALL

    if (!(IS_O_TYPE(A, O_FUNC) || IS_CF(A) || IS_O_TYPE(A, O_CFUNC))) { return -1; }
    regs  = stack->maybeGrow(regs, 256);
    int nExpectedArgs = IS_O_TYPE(A, O_FUNC) ? ((Func *)GET_OBJ(A))->proto->nArgs : NARGS_CFUNC;
    nEffArgs = prepareStackForCall(regs, nExpectedArgs, nEffArgs, gc);

    if (IS_CF(A) || IS_O_TYPE(A, O_CFUNC)) {
        if (IS_CF(A)) {
            tfunc f = GET_CF(A);
            *regs = f(this, CFunc::CFUNC_CALL, 0, regs, nEffArgs);
        } else {
            ((CFunc *) GET_OBJ(A))->call(this, regs, nEffArgs);
        }
        return 0;
    }

    unsigned code = 0;
    Value B;
    Value *ptrC;
    Func *activeFunc = (Func *) GET_OBJ(A);
    unsigned *pc = (unsigned *) activeFunc->proto->code.buf();

    static void *dispatch[] = {
#define _(name) &&name
#include "opcodes.inc"
#undef _
    };

    assert(sizeof(dispatch)/sizeof(dispatch[0]) == N_OPCODES);

    copyUpvals(activeFunc, regs);

    STEP;

 JMP:  pc += OD(code);    STEP;
 JT:   if (!IS_FALSE(*ptrC)) { pc += OD(code);  } STEP;
 JF:   if ( IS_FALSE(*ptrC)) { pc += OD(code);  } STEP;
 JLT:  if (lessThan(A, B))   { pc += OSC(code); } STEP;
 JNIS: if (A != B)           { pc += OSC(code); } STEP;

 FOR: 
    A = *(ptrC + 1);
    B = *(ptrC + 2);
    if (!IS_NUM(A) || !IS_NUM(B)) { goto error; } // E_FOR_NOT_NUMBER
    *ptrC = B;
    if (!(GET_NUM(B) < GET_NUM(A))) { pc += OD(code); }
    STEP;

 LOOP: {
        const double counter = GET_NUM(*ptrC) + 1;
        if (counter < GET_NUM(*(ptrC+1))) { pc += OD(code); }
        *ptrC = VAL_NUM(counter);
        STEP;
    }

 FUNC:
    assert(IS_PROTO(A));
    *ptrC = VAL_OBJ(Func::alloc(gc, PROTO(A), regs + 256, regs, OB(code)));
    STEP;

    // index, A[B]
 GETI: *ptrC = types->type(A)->indexGet(A, B); if (*ptrC == VERR) { goto error; } STEP;
 GETF: *ptrC = types->type(A)->fieldGet(A, B); if (*ptrC == VERR) { goto error; } STEP;
    
 SETI: if (!types->type(*ptrC)->indexSet(*ptrC, A, B)) { goto error; } STEP;
 SETF: if (!types->type(*ptrC)->fieldSet(*ptrC, A, B)) { goto error; } STEP;
    /*
      const int oa = OA(code);
      const int ob = OB(code);
      int top = max(oa, ob) + 1;
      top = max(top, activeFunc->proto->localsTop);
      Value *base = regs + top;
      printf("top %d\n", top);
      base[0] = A;
      base[1] = B;
      int cPos = ptrC - regs;
      DO_CALL(v, 2, regs, base, stack);
      regs[cPos] = base[0];
      break;
      if (*ptrC == VERR) { goto error; }
    */
        
 GETS: *ptrC = getSlice(gc, A, B, regs[OB(code)+1]); if (*ptrC==VERR) { goto error; } STEP;
 SETS: if (setSlice(*ptrC, A, regs[OA(code)+1], B)) { goto error; } STEP;

 RET: {
        regs[0] = A;
        Value *root = stack->base;
        gc->maybeCollect(root, regs - root + 1);
#if FAST_CALL
        if (!retInfo.size()) {
            return 0;
        }
        RetInfo *ri = retInfo.top();
        pc         = ri->pc;
        regs       = stack->base + ri->base;
        activeFunc = ri->func;
        retInfo.pop();
        copyUpvals(activeFunc, regs);
        STEP;
#else
        return 0;
#endif
    }

CALL: { 
        if (!IS_OBJ(A) && !IS_CF(A)) { goto error; } // E_CALL_NOT_FUNC
        int nEffArgs = OSB(code);
        assert(nEffArgs != 0);
        Value *base = ptrC;
#if FAST_CALL
        if (IS_O_TYPE(A, O_FUNC)) {
            Func *f = (Func *) GET_OBJ(A);
            Proto *proto = f->proto;
            prepareStackForCall(base, proto->nArgs, nEffArgs, gc);
            RetInfo *ret = retInfo.push();
            ret->pc    = pc;
            ret->base  = regs - stack->base;
            ret->func  = activeFunc;
            regs = stack->maybeGrow(base, 256);
            copyUpvals(f, regs);
            pc   = proto->code.buf();
            activeFunc = f;
        } else {
#endif
            int ret = DO_CALL(A, nEffArgs, regs, base, stack);
            if (ret) { goto error; }
#if FAST_CALL
        }
#endif
        STEP;
    }
    
 MOVEUP: {
        const int slot = regs + 256 - ptrC;
        activeFunc->setUp(slot, A);
    }
    
 MOVE_R: *ptrC = A; STEP;
 MOVE_I: *ptrC = VAL_NUM(OD(code)); STEP;
 MOVE_V: {
        int id = OA(code);
        *ptrC =
            id == CONST_NIL          ? VNIL :
            id == CONST_EMPTY_STRING ? EMPTY_STRING :
            id == CONST_EMPTY_ARRAY  ? VAL_OBJ(emptyArray->copy(gc)) :
            VAL_OBJ(emptyMap->copy(gc));
        STEP;
    }
    
 MOVE_C: {
        Value v = *pc | (((u64) *(pc+1)) << 32);
        pc += 2;
        if (IS_ARRAY(v)) {
            v = VAL_OBJ(ARRAY(v)->copy(gc));
        } else if (IS_MAP(v)) {
            v = VAL_OBJ(MAP(v)->copy(gc));
        }
        *ptrC = v;
        STEP;
    }
 LEN:    *ptrC = VAL_NUM(len(A)); STEP;
 NOTL:   *ptrC = IS_FALSE(A) ? TRUE : FALSE; STEP;
    // notb: *ptrC = IS_INT(A)? VAL_INT(~getInteger(A)):ERROR(E_WRONG_TYPE); STEP;

 ADD: *ptrC = doAdd(gc, A, B); if (*ptrC == VERR) { goto error; } STEP;
 SUB: *ptrC = BINOP(-, A, B); STEP;
 MUL: *ptrC = BINOP(*, A, B); STEP;
 DIV: *ptrC = BINOP(/, A, B); STEP;
 MOD: *ptrC = doMod(A, B); if (*ptrC == VERR) { goto error; } STEP;
 POW: *ptrC = doPow(A, B); if (*ptrC == VERR) { goto error; } STEP;

 AND: *ptrC = BITOP(&,  A, B); STEP;
 OR:  *ptrC = BITOP(|,  A, B); STEP;
 XOR: *ptrC = BITOP(^,  A, B); STEP;

 SHL_RR: ERR(!IS_NUM(B), E_WRONG_TYPE); *ptrC = doSHL(A, (int)GET_NUM(B)); STEP;
 SHR_RR: ERR(!IS_NUM(B), E_WRONG_TYPE); *ptrC = doSHR(A, (int)GET_NUM(B)); STEP;
 SHL_RI: *ptrC = doSHL(A, OSB(code));       STEP;
 SHR_RI: *ptrC = doSHR(A, OSB(code));       STEP;

 EQ:  *ptrC = equals(A, B)  ? TRUE : FALSE; STEP;
 NEQ: *ptrC = !equals(A, B) ? TRUE : FALSE; STEP;
 IS:  *ptrC = A == B ? TRUE : FALSE; STEP;
 NIS: *ptrC = A != B ? TRUE : FALSE; STEP;

 LT:  *ptrC = lessThan(A, B) ? TRUE : FALSE; STEP;
 LE:  *ptrC = (equals(A, B) || lessThan(A, B)) ? TRUE : FALSE; STEP;

 error: return pc - (unsigned *) activeFunc->proto->code.buf();
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void SobelEdge::setupFilterParameters()
{
  FilterParameterVector parameters;
  parameters.push_back(FilterParameter::New("Array to Process", "SelectedCellArrayPath", FilterParameterWidgetType::DataArraySelectionWidget, getSelectedCellArrayPath(), false, ""));
  QStringList linkedProps;
  linkedProps << "NewCellArrayName";
  parameters.push_back(LinkedBooleanFilterParameter::New("Save As New Array", "SaveAsNewArray", getSaveAsNewArray(), linkedProps, false));

  parameters.push_back(FilterParameter::New("Created Array Name", "NewCellArrayName", FilterParameterWidgetType::StringWidget, getNewCellArrayName(), false, ""));
  parameters.push_back(FilterParameter::New("Slice at a Time", "Slice", FilterParameterWidgetType::BooleanWidget, getSlice(), false));
  setFilterParameters(parameters);
}