Пример #1
0
/////////////////////////////////////////////////////////////////////////////////////
//// MAIN PROGRAM
/////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv) {
    char* argv_conf[MAXOPT]; // Input arguments from .hhdefaults file (first=1: argv_conf[0] is not used)
    int argc_conf;               // Number of arguments in argv_conf

    strcpy(par.infile, "");
    strcpy(par.outfile, "");
    strcpy(par.alnfile, "");

    //Default parameter settings
    par.nseqdis = MAXSEQ - 1;        // maximum number of sequences to be written
    par.showcons = 0;
    par.cons = 1;
    par.Ndiff = 0;
    par.max_seqid = 100;
    par.coverage = 0;
    par.pc_hhm_context_engine.pca = 0.0;  // no amino acid pseudocounts
    par.pc_hhm_nocontext_a = 0.0;  // no amino acid pseudocounts
    par.gapb = 0.0; // no transition pseudocounts

    // Make command line input globally available
    par.argv = argv;
    par.argc = argc;
    RemovePathAndExtension(program_name, argv[0]);

    // Enable changing verbose mode before defaults file and command line are processed
    int v = 2;
    for (int i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "-def"))
            par.readdefaultsfile = 1;
        else if (strcmp(argv[i], "-v") == 0) {
            v = atoi(argv[i + 1]);
        }
    }
    par.v = Log::from_int(v);
    Log::reporting_level() = par.v;

    par.SetDefaultPaths();

    // Read .hhdefaults file?
    if (par.readdefaultsfile) {
        // Process default otpions from .hhconfig file
        ReadDefaultsFile(argc_conf, argv_conf);
        ProcessArguments(argc_conf, argv_conf);
    }

    // Process command line options (they override defaults from .hhdefaults file)
    ProcessArguments(argc, argv);

    Alignment* qali = new Alignment(MAXSEQ, par.maxres);
    HMM* q = new HMM(MAXSEQDIS, par.maxres);        //Create a HMM with maximum of par.maxres match states

    // q is only available after maxres is known, so we had to move this here
    for (int i = 1; i <= argc - 1; i++) {
        if (!strcmp(argv[i], "-name") && (i < argc - 1)) {
            strmcpy(q->name, argv[++i], NAMELEN - 1); //copy longname to name...
            strmcpy(q->longname, argv[i], DESCLEN - 1);   //copy full name to longname
        }
    }

    // Check command line input and default values
    if (!*par.infile) {
        help();
        HH_LOG(ERROR) << "Input file is missing!" << std::endl;
        exit(4);
    }

    // Get basename
    RemoveExtension(q->file, par.infile); //Get basename of infile (w/o extension):

    // Outfile not given? Name it basename.hhm
    if (!*par.outfile && !*par.alnfile) {
        RemoveExtension(par.outfile, par.infile);
        strcat(par.outfile, ".seq");
    }

    // Prepare CS pseudocounts lib
    if (!par.nocontxt && *par.clusterfile) {
        InitializePseudocountsEngine(par, context_lib, crf, pc_hhm_context_engine,
                                     pc_hhm_context_mode, pc_prefilter_context_engine,
                                     pc_prefilter_context_mode);
    }

    // Set substitution matrix; adjust to query aa distribution if par.pcm==3
    SetSubstitutionMatrix(par.matrix, pb, P, R, S, Sim);

    // Read input file (HMM, HHM, or alignment format), and add pseudocounts etc.
    char input_format = 0;
    ReadQueryFile(par, par.infile, input_format, par.wg, q, qali, pb, S, Sim);

    // Same code as in PrepareQueryHMM(par.infile,input_format,q,qali), except that we add SS prediction
    // Add Pseudocounts, if no HMMER input
    if (input_format == 0) {
        // Transform transition freqs to lin space if not already done
        q->AddTransitionPseudocounts(par.gapd, par.gape, par.gapf, par.gapg,
                                     par.gaph, par.gapi, par.gapb, par.gapb);

        // Comput substitution matrix pseudocounts
        if (par.nocontxt) {
            // Generate an amino acid frequency matrix from f[i][a] with full pseudocount admixture (tau=1) -> g[i][a]
            q->PreparePseudocounts(R);
            // Add amino acid pseudocounts to query: p[i][a] = (1-tau)*f[i][a] + tau*g[i][a]
            q->AddAminoAcidPseudocounts(par.pc_hhm_nocontext_mode,
                                        par.pc_hhm_nocontext_a, par.pc_hhm_nocontext_b,
                                        par.pc_hhm_nocontext_c);
        }
        else {
            // Add full context specific pseudocounts to query
            q->AddContextSpecificPseudocounts(pc_hhm_context_engine,
                                              pc_hhm_context_mode);
        }
    }
    else {
        q->AddAminoAcidPseudocounts(0, par.pc_hhm_nocontext_a,
                                    par.pc_hhm_nocontext_b, par.pc_hhm_nocontext_c);
    }

    q->CalculateAminoAcidBackground(pb);

    if (par.columnscore == 5 && !q->divided_by_local_bg_freqs)
        q->DivideBySqrtOfLocalBackgroundFreqs(
            par.half_window_size_local_aa_bg_freqs, pb);

    // Write consensus sequence to sequence file
    // Consensus sequence is calculated in hhalignment.C, Alignment::FrequenciesAndTransitions()
    if (*par.outfile) {
        FILE* outf = NULL;
        if (strcmp(par.outfile, "stdout")) {
            outf = fopen(par.outfile, "a");
            if (!outf)
                OpenFileError(par.outfile, __FILE__, __LINE__, __func__);
        }
        else
            outf = stdout;
        // OLD
        //// ">name_consensus" -> ">name consensus"
        //strsubst(q->sname[q->nfirst],"_consensus"," consensus");
        //fprintf(outf,">%s\n%s\n",q->sname[q->nfirst],q->seq[q->nfirst]+1);
        // NEW (long header needed for NR30cons database)
        fprintf(outf, ">%s\n%s\n", q->longname, q->seq[q->nfirst] + 1);
        fclose(outf);
    }

    // Print A3M/A2M/FASTA output alignment
    if (*par.alnfile) {
        HalfAlignment qa;
        int n = imin(q->n_display,
                     par.nseqdis + (q->nss_dssp >= 0) + (q->nss_pred >= 0)
                     + (q->nss_conf >= 0) + (q->ncons >= 0));
        qa.Set(q->name, q->seq, q->sname, n, q->L, q->nss_dssp, q->nss_pred,
               q->nss_conf, q->nsa_dssp, q->ncons);

        if (par.outformat == 1)
            qa.BuildFASTA();
        else if (par.outformat == 2)
            qa.BuildA2M();
        else if (par.outformat == 3)
            qa.BuildA3M();
        if (qali->readCommentLine)
            qa.Print(par.alnfile, par.append, qali->longname); // print alignment to outfile
        else
            qa.Print(par.alnfile, par.append);   // print alignment to outfile
    }

    delete qali;
    delete q;

    DeletePseudocountsEngine(context_lib, crf, pc_hhm_context_engine,
                             pc_hhm_context_mode, pc_prefilter_context_engine,
                             pc_prefilter_context_mode);
}
Пример #2
0
/*!
***********************************************************************
* \brief
*    Fast sub pixel block motion search to support EPZS
***********************************************************************
*/
distblk                                                   //  ==> minimum motion cost after search
EPZS_sub_pel_motion_estimation ( Macroblock *currMB,      // <--  current Macroblock
                                 MotionVector *pred,      // <--  motion vector predictor in sub-pel units
                                 MEBlock  *mv_block,      // <--  motion vector information
                                 distblk   min_mcost,     // <--  minimum motion cost (cost for center or huge value)
                                 int*      lambda         // <--  lagrangian parameter for determining motion cost
                                )
{
  VideoParameters *p_Vid = currMB->p_Vid;
  Slice *currSlice = currMB->p_Slice;
  EPZSParameters *p_EPZS = currSlice->p_EPZS;
  int   pos, best_pos = 0, second_pos = 0;
  distblk mcost;
  distblk second_mcost = DISTBLK_MAX;
  int   max_pos2     = ( (!p_Vid->start_me_refinement_hp || !p_Vid->start_me_refinement_qp) ? imax(1, mv_block->search_pos2) : mv_block->search_pos2);

  int list = mv_block->list;
  int cur_list = list + currMB->list_offset;
  short ref = mv_block->ref_idx;
  StorablePicture *ref_picture = currSlice->listX[cur_list][ref];
  MotionVector *mv  = &mv_block->mv[list];
  MotionVector cand;
  MotionVector padded_mv = pad_MVs (*mv,   mv_block);
  MotionVector pred_mv   = pad_MVs (*pred, mv_block);

  int start_pos = 5, end_pos = max_pos2;
  int lambda_factor = lambda[H_PEL];
  distblk lambda_dist   = weighted_cost(lambda_factor, 2);
  distblk sub_threshold = p_EPZS->subthres[mv_block->blocktype] + lambda_dist;

  /*********************************
  *****                       *****
  *****  HALF-PEL REFINEMENT  *****
  *****                       *****
  *********************************/

  //===== loop over search positions =====
  for (best_pos = 0, pos = p_Vid->start_me_refinement_hp; pos < imin(5, max_pos2); ++pos)
  {
    cand = add_MVs(search_point_hp[pos], &padded_mv);

    //----- set motion vector cost -----
    mcost = mv_cost (p_Vid, lambda_factor, &cand, &pred_mv);        
    if (mcost < second_mcost)
    {
      mcost += mv_block->computePredHPel(ref_picture, mv_block, second_mcost - mcost, &cand);

      if (mcost < min_mcost)
      {
        second_mcost = min_mcost;
        second_pos  = best_pos;
        min_mcost = mcost;
        best_pos  = pos;
      }
      else if (mcost < second_mcost)
      {
        second_mcost = mcost;
        second_pos  = pos;
      }
    }
  }

  if (best_pos ==0 && (pred->mv_x == mv->mv_x) && (pred->mv_y == mv->mv_y) && min_mcost < sub_threshold)
  {
    return min_mcost;
  }

  if(mv_block->search_pos2 >= 9)
  {
    if (best_pos !=0 || (iabs(pred->mv_x - mv->mv_x) + iabs(pred->mv_y - mv->mv_y)))
    {
      start_pos = next_start_pos[best_pos][second_pos];
      end_pos   = next_end_pos[best_pos][second_pos];      
      
      for (pos = start_pos; pos < end_pos; ++pos)
      {
        cand = add_MVs(search_point_hp[pos], &padded_mv);

        //----- set motion vector cost -----
        mcost = mv_cost (p_Vid, lambda_factor, &cand, &pred_mv);

        if (mcost < min_mcost)
        {
          mcost += mv_block->computePredHPel( ref_picture, mv_block, min_mcost - mcost, &cand);

          if (mcost < min_mcost)
          {
            min_mcost = mcost;
            best_pos  = pos;
          }
        }
      }
    }
  }

  if (best_pos)
  {
    add_mvs(mv, &search_point_hp[best_pos]);
    padded_mv = pad_MVs (*mv, mv_block);
  }

  /************************************
  *****                          *****
  *****  QUARTER-PEL REFINEMENT  *****
  *****                          *****
  ************************************/
  end_pos = (min_mcost < sub_threshold) ? 1 : 5;
  second_mcost = DISTBLK_MAX;

  if ( !p_Vid->start_me_refinement_qp )
  {
    best_pos = -1;
    min_mcost = DISTBLK_MAX;   
  }
  else
  {
    best_pos = 0;
  }
  lambda_factor = lambda[Q_PEL];      
  
  //===== loop over search positions =====
  for (pos = p_Vid->start_me_refinement_qp; pos < end_pos; ++pos)
  {    
    cand = add_MVs(search_point_qp[pos], &padded_mv);

    //----- set motion vector cost -----
    mcost  = mv_cost (p_Vid, lambda_factor, &cand, &pred_mv);

    if (mcost < second_mcost)
    {
      mcost += mv_block->computePredQPel(ref_picture, mv_block, second_mcost - mcost, &cand);

      if (mcost < min_mcost)
      {
        second_mcost = min_mcost;
        second_pos  = best_pos;
        min_mcost = mcost;
        best_pos  = pos;
      }
      else if (mcost < second_mcost)
      {
        second_mcost = mcost;
        second_pos  = pos;
      }
    }
  }

  //if (best_pos ==0 && (pred->mv_x == mv->mv_x) && (pred->mv_y == mv->mv_y) && min_mcost < sub_threshold)
  if ( (min_mcost > sub_threshold))
  {

    if (best_pos !=0 || (iabs(pred->mv_x - mv->mv_x) + iabs(pred->mv_y - mv->mv_y)))
    {
      start_pos = next_start_pos[best_pos][second_pos];
      end_pos   = next_end_pos[best_pos][second_pos];      

      for (pos = start_pos; pos < end_pos; ++pos)
      {
        cand = add_MVs(search_point_qp[pos], &padded_mv);

        //----- set motion vector cost -----
        mcost = mv_cost (p_Vid, lambda_factor, &cand, &pred_mv);

        if (mcost < min_mcost) 
        {
          mcost += mv_block->computePredQPel(ref_picture, mv_block, min_mcost - mcost, &cand);

          if (mcost < min_mcost)
          {
            min_mcost = mcost;
            best_pos  = pos;
          }
        }
      }
    }
  }

  if (best_pos)
  {
    add_mvs(mv, &search_point_qp[best_pos]);
  }

  //===== return minimum motion cost =====
  return min_mcost;
}
Пример #3
0
int main()
{
    char c = 'O';
    char blank = ' ';
    int code0 = 0;
    int code1 = 0;
    int px = 0;
    int py = 0;
    int screenWidth = 0;
    int screenHeight = 0;

    GetWH(&screenWidth, &screenHeight);

    COORD position;

    position.X = px = screenWidth / 2;
    position.Y = py = screenHeight / 2;

    /* Output the char at initial position. */
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);
    std::cout << c;

    while(true)
    {
        code0 = (int)_getch();    

        /* Press ESC to quit. */
        if(code0 == 27)
        {
            break;
        }

        code1 = (int)_getch();

        switch(code1)
        {
        case KEY_UP:
            py = imax(0, py - 1);
            break;
        case KEY_LEFT:
            px = imax(0, px - 1);            
            break;
        case KEY_RIGHT:
            px= imin(screenWidth, px + 1);
            break;
        case KEY_DOWN:
            py = imin(screenHeight, py + 1);            
            break;
        default:
            break;
        }

        ClearConsole();

        position.X = px;
        position.Y = py;

        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);

        /* Output the char at the new position. */
        std::cout << c;
    }

    return 0;
}
Пример #4
0
/*!
 ************************************************************************
 * \brief
 *    Initialize reference lists for a B Slice
 *
 ************************************************************************
 */
void init_lists_b_slice_mvc(Slice *currSlice)
{
  VideoParameters *p_Vid = currSlice->p_Vid;
  DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;

  unsigned int i;
  int j;

  int list0idx = 0;
  int list0idx_1 = 0;
  int listltidx = 0;

  FrameStore **fs_list0;
  FrameStore **fs_list1;
  FrameStore **fs_listlt;

  int currPOC = currSlice->ThisPOC;
  int curr_view_id = currSlice->view_id;
  int anchor_pic_flag = currSlice->anchor_pic_flag;

  currSlice->listinterviewidx0 = 0;
  currSlice->listinterviewidx1 = 0;

  {
    // B-Slice
    if (currSlice->structure == FRAME)
    {
      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used==3)
        {
          if ((p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Dpb->fs_ref[i]->frame->is_long_term) && (p_Dpb->fs_ref[i]->frame->view_id == curr_view_id))
          {
            if (currSlice->framepoc >= p_Dpb->fs_ref[i]->frame->poc) //!KS use >= for error concealment
              //            if (p_Vid->framepoc > p_Dpb->fs_ref[i]->frame->poc)
            {
              currSlice->listX[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
            }
          }
        }
      }
      qsort((void *)currSlice->listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
      list0idx_1 = list0idx;
      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used==3)
        {
          if ((p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Dpb->fs_ref[i]->frame->is_long_term) && (p_Dpb->fs_ref[i]->frame->view_id == curr_view_id))
          {
            if (currSlice->framepoc < p_Dpb->fs_ref[i]->frame->poc)
            {
              currSlice->listX[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
            }
          }
        }
      }
      qsort((void *)&currSlice->listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);

      for (j=0; j<list0idx_1; j++)
      {
        currSlice->listX[1][list0idx-list0idx_1+j]=currSlice->listX[0][j];
      }
      for (j=list0idx_1; j<list0idx; j++)
      {
        currSlice->listX[1][j-list0idx_1]=currSlice->listX[0][j];
      }

      currSlice->listXsize[0] = currSlice->listXsize[1] = (char) list0idx;

      //      printf("currSlice->listX[0] currPoc=%d (Poc): ", currSlice->framepoc); for (i=0; i<currSlice->listXsize[0]; i++){printf ("%d  ", currSlice->listX[0][i]->poc);} printf("\n");
      //      printf("currSlice->listX[1] currPoc=%d (Poc): ", currSlice->framepoc); for (i=0; i<currSlice->listXsize[1]; i++){printf ("%d  ", currSlice->listX[1][i]->poc);} printf("\n");

      // long term handling
      for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ltref[i]->is_used==3)
        {
          if (p_Dpb->fs_ltref[i]->frame->is_long_term && (p_Dpb->fs_ltref[i]->frame->view_id == curr_view_id))
          {
            currSlice->listX[0][list0idx]   = p_Dpb->fs_ltref[i]->frame;
            currSlice->listX[1][list0idx++] = p_Dpb->fs_ltref[i]->frame;
          }
        }
      }
      qsort((void *)&currSlice->listX[0][(short) currSlice->listXsize[0]], list0idx - currSlice->listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
      qsort((void *)&currSlice->listX[1][(short) currSlice->listXsize[0]], list0idx - currSlice->listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
      currSlice->listXsize[0] = currSlice->listXsize[1] = (char) list0idx;
    }
    else
    {
      fs_list0 = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==fs_list0)
        no_mem_exit("init_lists: fs_list0");
      fs_list1 = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==fs_list1)
        no_mem_exit("init_lists: fs_list1");
      fs_listlt = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==fs_listlt)
        no_mem_exit("init_lists: fs_listlt");

      currSlice->listXsize[0] = 0;
      currSlice->listXsize[1] = 1;

      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used)
        {
          if (currSlice->ThisPOC >= p_Dpb->fs_ref[i]->poc && (p_Dpb->fs_ref[i]->view_id == curr_view_id))
          {
            fs_list0[list0idx++] = p_Dpb->fs_ref[i];
          }
        }
      }
      qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_poc_desc);
      list0idx_1 = list0idx;
      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used)
        {
          if (currSlice->ThisPOC < p_Dpb->fs_ref[i]->poc && (p_Dpb->fs_ref[i]->view_id == curr_view_id))
          {
            fs_list0[list0idx++] = p_Dpb->fs_ref[i];
          }
        }
      }
      qsort((void *)&fs_list0[list0idx_1], list0idx-list0idx_1, sizeof(FrameStore*), compare_fs_by_poc_asc);

      for (j=0; j<list0idx_1; j++)
      {
        fs_list1[list0idx-list0idx_1+j]=fs_list0[j];
      }
      for (j=list0idx_1; j<list0idx; j++)
      {
        fs_list1[j-list0idx_1]=fs_list0[j];
      }

      //      printf("fs_list0 currPoc=%d (Poc): ", currSlice->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d  ", fs_list0[i]->poc);} printf("\n");
      //      printf("fs_list1 currPoc=%d (Poc): ", currSlice->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d  ", fs_list1[i]->poc);} printf("\n");

      currSlice->listXsize[0] = 0;
      currSlice->listXsize[1] = 0;
      gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listX[0], &currSlice->listXsize[0], 0);
      gen_pic_list_from_frame_list(currSlice->structure, fs_list1, list0idx, currSlice->listX[1], &currSlice->listXsize[1], 0);

      //      printf("currSlice->listX[0] currPoc=%d (Poc): ", currSlice->framepoc); for (i=0; i<currSlice->listXsize[0]; i++){printf ("%d  ", currSlice->listX[0][i]->poc);} printf("\n");
      //      printf("currSlice->listX[1] currPoc=%d (Poc): ", currSlice->framepoc); for (i=0; i<currSlice->listXsize[1]; i++){printf ("%d  ", currSlice->listX[1][i]->poc);} printf("\n");

      // long term handling
      for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ltref[i]->view_id == curr_view_id)
          fs_listlt[listltidx++]=p_Dpb->fs_ltref[i];
      }

      qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);

      gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listX[0], &currSlice->listXsize[0], 1);
      gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listX[1], &currSlice->listXsize[1], 1);

      free(fs_list0);
      free(fs_list1);
      free(fs_listlt);
    }
  }

  if ((currSlice->listXsize[0] == currSlice->listXsize[1]) && (currSlice->listXsize[0] > 1))
  {
    // check if lists are identical, if yes swap first two elements of currSlice->listX[1]
    int diff=0;
    for (j = 0; j< currSlice->listXsize[0]; j++)
    {
      if (currSlice->listX[0][j] != currSlice->listX[1][j])
      {
        diff = 1;
        break;
      }
    }
    if (!diff)
    {
      StorablePicture *tmp_s = currSlice->listX[1][0];
      currSlice->listX[1][0]=currSlice->listX[1][1];
      currSlice->listX[1][1]=tmp_s;
    }
  }

  if (currSlice->svc_extension_flag == 0)
  {
    // B-Slice
    currSlice->fs_listinterview0 = calloc(p_Dpb->size, sizeof (FrameStore*));
    if (NULL==currSlice->fs_listinterview0)
      no_mem_exit("init_lists: fs_listinterview0");
    currSlice->fs_listinterview1 = calloc(p_Dpb->size, sizeof (FrameStore*));
    if (NULL==currSlice->fs_listinterview1)
      no_mem_exit("init_lists: fs_listinterview1");
    list0idx = currSlice->listXsize[0];

    if (currSlice->structure == FRAME)
    {
      append_interview_list(p_Dpb, 0, 0, currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_view_id, anchor_pic_flag);
      append_interview_list(p_Dpb, 0, 1, currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_view_id, anchor_pic_flag);

      for (i=0; i<(unsigned int)currSlice->listinterviewidx0; i++)
      {
        currSlice->listX[0][list0idx++]=currSlice->fs_listinterview0[i]->frame;
      }
      currSlice->listXsize[0] = (char) list0idx;
      list0idx = currSlice->listXsize[1];
      for (i=0; i<(unsigned int)currSlice->listinterviewidx1; i++)
      {
        currSlice->listX[1][list0idx++] = currSlice->fs_listinterview1[i]->frame;
      }
      currSlice->listXsize[1] = (char) list0idx;
    }
    else
    {
      append_interview_list(p_Dpb, currSlice->structure, 0, currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_view_id, anchor_pic_flag);
      gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0, currSlice->listinterviewidx0, currSlice->listX[0], &currSlice->listXsize[0]);
      append_interview_list(p_Dpb, currSlice->structure, 1, currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_view_id, anchor_pic_flag);
      gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview1, currSlice->listinterviewidx1, currSlice->listX[1], &currSlice->listXsize[1]);	
    }    
  }

  // set max size
  currSlice->listXsize[0] = (char) imin (currSlice->listXsize[0], currSlice->num_ref_idx_active[LIST_0]);
  currSlice->listXsize[1] = (char) imin (currSlice->listXsize[1], currSlice->num_ref_idx_active[LIST_1]);

  // set the unused list entries to NULL
  for (i=currSlice->listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
  {
    currSlice->listX[0][i] = p_Vid->no_reference_picture;
  }
  for (i=currSlice->listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
  {
    currSlice->listX[1][i] = p_Vid->no_reference_picture;
  }
/*#if PRINTREFLIST
  // print out for debug purpose
  if((p_Vid->profile_idc == MVC_HIGH || p_Vid->profile_idc == STEREO_HIGH) && currSlice->current_slice_nr==0)
  {
    if((currSlice->listXsize[0]>0) || (currSlice->listXsize[1]>0))
      printf("\n");
    if(currSlice->listXsize[0]>0)
    {
      printf(" ** (CurViewID:%d) %s Ref Pic List 0 ****\n", currSlice->view_id, currSlice->structure==FRAME ? "FRM":(currSlice->structure==TOP_FIELD ? "TOP":"BOT"));
      for(i=0; i<(unsigned int)(currSlice->listXsize[0]); i++)	//ref list 0
      {
        printf("   %2d -> POC: %4d PicNum: %4d ViewID: %d\n", i, currSlice->listX[0][i]->poc, currSlice->listX[0][i]->pic_num, currSlice->listX[0][i]->view_id);
      }
    }
    if(currSlice->listXsize[1]>0)
    {
      printf(" ** (CurViewID:%d) %s Ref Pic List 1 ****\n", currSlice->view_id, currSlice->structure==FRAME ? "FRM":(currSlice->structure==TOP_FIELD ? "TOP":"BOT"));
      for(i=0; i<(unsigned int)(currSlice->listXsize[1]); i++)	//ref list 1
      {
        printf("   %2d -> POC: %4d PicNum: %4d ViewID: %d\n", i, currSlice->listX[1][i]->poc, currSlice->listX[1][i]->pic_num, currSlice->listX[1][i]->view_id);
      }
    }
  }
#endif*/
}
Пример #5
0
void GrMouseWarp(int x, int y)
{
    MOUINFO->xpos = imax(MOUINFO->xmin, imin(MOUINFO->xmax, x));
    MOUINFO->ypos = imax(MOUINFO->ymin, imin(MOUINFO->ymax, y));
    GrMouseUpdateCursor();
}
Пример #6
0
struct mbuf *
ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt,
    int srcrt)
{
	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
	struct sockaddr_in6 *dst;
	struct rtentry *rt;
	int error, type = 0, code = 0;
	boolean_t proxy = FALSE;
	struct mbuf *mcopy = NULL;
	struct ifnet *ifp, *rcvifp, *origifp;	/* maybe unnecessary */
	u_int32_t inzone, outzone, len;
	struct in6_addr src_in6, dst_in6;
	uint64_t curtime = net_uptime();
#if IPSEC
	struct secpolicy *sp = NULL;
#endif
	unsigned int ifscope = IFSCOPE_NONE;
#if PF
	struct pf_mtag *pf_mtag;
#endif /* PF */

	/*
	 * In the prefix proxying case, the route to the proxied node normally
	 * gets created by nd6_prproxy_ns_output(), as part of forwarding a
	 * NS (NUD/AR) packet to the proxied node.  In the event that such
	 * packet did not arrive in time before the correct route gets created,
	 * ip6_input() would have performed a rtalloc() which most likely will
	 * create the wrong cloned route; this route points back to the same
	 * interface as the inbound interface, since the parent non-scoped
	 * prefix route points there.  Therefore we check if that is the case
	 * and perform the necessary fixup to get the correct route installed.
	 */
	if (!srcrt && nd6_prproxy &&
	    (rt = ip6forward_rt->ro_rt) != NULL && (rt->rt_flags & RTF_PROXY)) {
		nd6_proxy_find_fwdroute(m->m_pkthdr.rcvif, ip6forward_rt);
		if ((rt = ip6forward_rt->ro_rt) != NULL)
			ifscope = rt->rt_ifp->if_index;
	}

#if PF
	pf_mtag = pf_find_mtag(m);
	if (pf_mtag != NULL && pf_mtag->pftag_rtableid != IFSCOPE_NONE)
		ifscope = pf_mtag->pftag_rtableid;

	/*
	 * If the caller provides a route which is on a different interface
	 * than the one specified for scoped forwarding, discard the route
	 * and do a lookup below.
	 */
	if (ifscope != IFSCOPE_NONE && (rt = ip6forward_rt->ro_rt) != NULL) {
		RT_LOCK(rt);
		if (rt->rt_ifp->if_index != ifscope) {
			RT_UNLOCK(rt);
			ROUTE_RELEASE(ip6forward_rt);
			rt = NULL;
		} else {
			RT_UNLOCK(rt);
		}
	}
#endif /* PF */

#if IPSEC
	/*
	 * Check AH/ESP integrity.
	 */
	/*
	 * Don't increment ip6s_cantforward because this is the check
	 * before forwarding packet actually.
	 */
	if (ipsec_bypass == 0) {
		if (ipsec6_in_reject(m, NULL)) {
			IPSEC_STAT_INCREMENT(ipsec6stat.in_polvio);
			m_freem(m);
			return (NULL);
		}
	}
#endif /*IPSEC*/

	/*
	 * Do not forward packets to multicast destination.
	 * Do not forward packets with unspecified source.  It was discussed
	 * in July 2000, on ipngwg mailing list.
	 */
	if ((m->m_flags & (M_BCAST|M_MCAST)) != 0 ||
	    IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
	    IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
		ip6stat.ip6s_cantforward++;
		/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
		if (ip6_log_time + ip6_log_interval < curtime) {
			ip6_log_time = curtime;
			log(LOG_DEBUG,
			    "cannot forward "
			    "from %s to %s nxt %d received on %s\n",
			    ip6_sprintf(&ip6->ip6_src),
			    ip6_sprintf(&ip6->ip6_dst),
			    ip6->ip6_nxt,
			    if_name(m->m_pkthdr.rcvif));
		}
		m_freem(m);
		return (NULL);
	}

	if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
		/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
		icmp6_error_flag(m, ICMP6_TIME_EXCEEDED,
				ICMP6_TIME_EXCEED_TRANSIT, 0, 0);
		return (NULL);
	}

	/*
	 * See if the destination is a proxied address, and if so pretend
	 * that it's for us.  This is mostly to handle NUD probes against
	 * the proxied addresses.  We filter for ICMPv6 here and will let
	 * icmp6_input handle the rest.
	 */
	if (!srcrt && nd6_prproxy) {
		VERIFY(!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst));
		proxy = nd6_prproxy_isours(m, ip6, ip6forward_rt, ifscope);
		/*
		 * Don't update hop limit while proxying; RFC 4389 4.1.
		 * Also skip IPsec forwarding path processing as this
		 * packet is not to be forwarded.
		 */
		if (proxy)
			goto skip_ipsec;
	}

	ip6->ip6_hlim -= IPV6_HLIMDEC;

	/*
	 * Save at most ICMPV6_PLD_MAXLEN (= the min IPv6 MTU -
	 * size of IPv6 + ICMPv6 headers) bytes of the packet in case
	 * we need to generate an ICMP6 message to the src.
	 * Thanks to M_EXT, in most cases copy will not occur.
	 *
	 * It is important to save it before IPsec processing as IPsec
	 * processing may modify the mbuf.
	 */
	mcopy = m_copy(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN));

#if IPSEC
	if (ipsec_bypass != 0)
		goto skip_ipsec;
	/* get a security policy for this packet */
	sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, IP_FORWARDING,
	    &error);
	if (sp == NULL) {
		IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
		ip6stat.ip6s_cantforward++;
		if (mcopy) {
#if 0
			/* XXX: what icmp ? */
#else
			m_freem(mcopy);
#endif
		}
		m_freem(m);
		return (NULL);
	}

	error = 0;

	/* check policy */
	switch (sp->policy) {
	case IPSEC_POLICY_DISCARD:
        case IPSEC_POLICY_GENERATE:
		/*
		 * This packet is just discarded.
		 */
		IPSEC_STAT_INCREMENT(ipsec6stat.out_polvio);
		ip6stat.ip6s_cantforward++;
		key_freesp(sp, KEY_SADB_UNLOCKED);
		if (mcopy) {
#if 0
			/* XXX: what icmp ? */
#else
			m_freem(mcopy);
#endif
		}
		m_freem(m);
		return (NULL);

	case IPSEC_POLICY_BYPASS:
	case IPSEC_POLICY_NONE:
		/* no need to do IPsec. */
		key_freesp(sp, KEY_SADB_UNLOCKED);
		goto skip_ipsec;

	case IPSEC_POLICY_IPSEC:
		if (sp->req == NULL) {
			/* XXX should be panic ? */
			printf("ip6_forward: No IPsec request specified.\n");
			ip6stat.ip6s_cantforward++;
			key_freesp(sp, KEY_SADB_UNLOCKED);
			if (mcopy) {
#if 0
				/* XXX: what icmp ? */
#else
				m_freem(mcopy);
#endif
			}
			m_freem(m);
			return (NULL);
		}
		/* do IPsec */
		break;

	case IPSEC_POLICY_ENTRUST:
	default:
		/* should be panic ?? */
		printf("ip6_forward: Invalid policy found. %d\n", sp->policy);
		key_freesp(sp, KEY_SADB_UNLOCKED);
		goto skip_ipsec;
	}

    {
	struct ipsec_output_state state;

	/*
	 * All the extension headers will become inaccessible
	 * (since they can be encrypted).
	 * Don't panic, we need no more updates to extension headers
	 * on inner IPv6 packet (since they are now encapsulated).
	 *
	 * IPv6 [ESP|AH] IPv6 [extension headers] payload
	 */
	bzero(&state, sizeof(state));
	state.m = m;
	state.dst = NULL;	/* update at ipsec6_output_tunnel() */

	error = ipsec6_output_tunnel(&state, sp, 0);
	key_freesp(sp, KEY_SADB_UNLOCKED);
	if (state.tunneled == 4) {
		ROUTE_RELEASE(&state.ro);
		return (NULL);  /* packet is gone - sent over IPv4 */
	}

	m = state.m;
	ROUTE_RELEASE(&state.ro);

	if (error) {
		/* mbuf is already reclaimed in ipsec6_output_tunnel. */
		switch (error) {
		case EHOSTUNREACH:
		case ENETUNREACH:
		case EMSGSIZE:
		case ENOBUFS:
		case ENOMEM:
			break;
		default:
			printf("ip6_output (ipsec): error code %d\n", error);
			/* fall through */
		case ENOENT:
			/* don't show these error codes to the user */
			break;
		}
		ip6stat.ip6s_cantforward++;
		if (mcopy) {
#if 0
			/* XXX: what icmp ? */
#else
			m_freem(mcopy);
#endif
		}
		m_freem(m);
		return (NULL);
	}
    }
#endif /* IPSEC */
    skip_ipsec:

	dst = (struct sockaddr_in6 *)&ip6forward_rt->ro_dst;
	if ((rt = ip6forward_rt->ro_rt) != NULL) {
		RT_LOCK(rt);
		/* Take an extra ref for ourselves */
		RT_ADDREF_LOCKED(rt);
	}

	VERIFY(rt == NULL || rt == ip6forward_rt->ro_rt);
	if (!srcrt) {
		/*
		 * ip6forward_rt->ro_dst.sin6_addr is equal to ip6->ip6_dst
		 */
		if (ROUTE_UNUSABLE(ip6forward_rt)) {
			if (rt != NULL) {
				/* Release extra ref */
				RT_REMREF_LOCKED(rt);
				RT_UNLOCK(rt);
			}
			ROUTE_RELEASE(ip6forward_rt);

			/* this probably fails but give it a try again */
			rtalloc_scoped_ign((struct route *)ip6forward_rt,
			    RTF_PRCLONING, ifscope);
			if ((rt = ip6forward_rt->ro_rt) != NULL) {
				RT_LOCK(rt);
				/* Take an extra ref for ourselves */
				RT_ADDREF_LOCKED(rt);
			}
		}

		if (rt == NULL) {
			ip6stat.ip6s_noroute++;
			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_noroute);
			if (mcopy)
				icmp6_error(mcopy, ICMP6_DST_UNREACH,
					    ICMP6_DST_UNREACH_NOROUTE, 0);
			m_freem(m);
			return (NULL);
		}
		RT_LOCK_ASSERT_HELD(rt);
	} else if (ROUTE_UNUSABLE(ip6forward_rt) ||
	    !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr)) {
		if (rt != NULL) {
			/* Release extra ref */
			RT_REMREF_LOCKED(rt);
			RT_UNLOCK(rt);
		}
		ROUTE_RELEASE(ip6forward_rt);

		bzero(dst, sizeof(*dst));
		dst->sin6_len = sizeof(struct sockaddr_in6);
		dst->sin6_family = AF_INET6;
		dst->sin6_addr = ip6->ip6_dst;

		rtalloc_scoped_ign((struct route *)ip6forward_rt,
		    RTF_PRCLONING, ifscope);
		if ((rt = ip6forward_rt->ro_rt) == NULL) {
			ip6stat.ip6s_noroute++;
			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_noroute);
			if (mcopy)
				icmp6_error(mcopy, ICMP6_DST_UNREACH,
				    ICMP6_DST_UNREACH_NOROUTE, 0);
			m_freem(m);
			return (NULL);
		}
		RT_LOCK(rt);
		/* Take an extra ref for ourselves */
		RT_ADDREF_LOCKED(rt);
	}

	/*
	 * Source scope check: if a packet can't be delivered to its
	 * destination for the reason that the destination is beyond the scope
	 * of the source address, discard the packet and return an icmp6
	 * destination unreachable error with Code 2 (beyond scope of source
	 * address) unless we are proxying (source address is link local
	 * for NUDs.)  We use a local copy of ip6_src, since in6_setscope()
	 * will possibly modify its first argument.
	 * [draft-ietf-ipngwg-icmp-v3-04.txt, Section 3.1]
	 */
	src_in6 = ip6->ip6_src;
	if (in6_setscope(&src_in6, rt->rt_ifp, &outzone)) {
		/* XXX: this should not happen */
		ip6stat.ip6s_cantforward++;
		ip6stat.ip6s_badscope++;
		m_freem(m);
		return (NULL);
	}
	if (in6_setscope(&src_in6, m->m_pkthdr.rcvif, &inzone)) {
		ip6stat.ip6s_cantforward++;
		ip6stat.ip6s_badscope++;
		m_freem(m);
		return (NULL);
	}

	if (inzone != outzone && !proxy) {
		ip6stat.ip6s_cantforward++;
		ip6stat.ip6s_badscope++;
		in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard);

		if (ip6_log_time + ip6_log_interval < curtime) {
			ip6_log_time = curtime;
			log(LOG_DEBUG,
			    "cannot forward "
			    "src %s, dst %s, nxt %d, rcvif %s, outif %s\n",
			    ip6_sprintf(&ip6->ip6_src),
			    ip6_sprintf(&ip6->ip6_dst),
			    ip6->ip6_nxt,
			    if_name(m->m_pkthdr.rcvif), if_name(rt->rt_ifp));
		}
		/* Release extra ref */
		RT_REMREF_LOCKED(rt);
		RT_UNLOCK(rt);
		if (mcopy) {
			icmp6_error(mcopy, ICMP6_DST_UNREACH,
				    ICMP6_DST_UNREACH_BEYONDSCOPE, 0);
		}
		m_freem(m);
		return (NULL);
	}

	/*
	 * Destination scope check: if a packet is going to break the scope
	 * zone of packet's destination address, discard it.  This case should
	 * usually be prevented by appropriately-configured routing table, but
	 * we need an explicit check because we may mistakenly forward the
	 * packet to a different zone by (e.g.) a default route.
	 */
	dst_in6 = ip6->ip6_dst;
	if (in6_setscope(&dst_in6, m->m_pkthdr.rcvif, &inzone) != 0 ||
	    in6_setscope(&dst_in6, rt->rt_ifp, &outzone) != 0 ||
	    inzone != outzone) {
		ip6stat.ip6s_cantforward++;
		ip6stat.ip6s_badscope++;
		m_freem(m);
		return (NULL);
	}

	if (m->m_pkthdr.len > rt->rt_ifp->if_mtu) {
		in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
		if (mcopy) {
			uint32_t mtu;
#if IPSEC
			struct secpolicy *sp2;
			int ipsecerror;
			size_t ipsechdrsiz;
#endif

			mtu = rt->rt_ifp->if_mtu;
#if IPSEC
			/*
			 * When we do IPsec tunnel ingress, we need to play
			 * with the link value (decrement IPsec header size
			 * from mtu value).  The code is much simpler than v4
			 * case, as we have the outgoing interface for
			 * encapsulated packet as "rt->rt_ifp".
			 */
			sp2 = ipsec6_getpolicybyaddr(mcopy, IPSEC_DIR_OUTBOUND,
				IP_FORWARDING, &ipsecerror);
			if (sp2) {
				ipsechdrsiz = ipsec6_hdrsiz(mcopy,
					IPSEC_DIR_OUTBOUND, NULL);
				if (ipsechdrsiz < mtu)
					mtu -= ipsechdrsiz;
				key_freesp(sp2, KEY_SADB_UNLOCKED);
			}
			/*
			 * if mtu becomes less than minimum MTU,
			 * tell minimum MTU (and I'll need to fragment it).
			 */
			if (mtu < IPV6_MMTU)
				mtu = IPV6_MMTU;
#endif
			/* Release extra ref */
			RT_REMREF_LOCKED(rt);
			RT_UNLOCK(rt);
			icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
		} else {
			/* Release extra ref */
			RT_REMREF_LOCKED(rt);
			RT_UNLOCK(rt);
		}
		m_freem(m);
		return (NULL);
 	}

	if (rt->rt_flags & RTF_GATEWAY)
		dst = (struct sockaddr_in6 *)(void *)rt->rt_gateway;

	/*
	 * If we are to forward the packet using the same interface
	 * as one we got the packet from, perhaps we should send a redirect
	 * to sender to shortcut a hop.
	 * Only send redirect if source is sending directly to us,
	 * and if packet was not source routed (or has any options).
	 * Also, don't send redirect if forwarding using a route
	 * modified by a redirect.
	 */
	if (!proxy &&
	    ip6_sendredirects && rt->rt_ifp == m->m_pkthdr.rcvif && !srcrt &&
	    (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
		if ((rt->rt_ifp->if_flags & IFF_POINTOPOINT) != 0) {
			/*
			 * If the incoming interface is equal to the outgoing
			 * one, and the link attached to the interface is
			 * point-to-point, then it will be highly probable
			 * that a routing loop occurs. Thus, we immediately
			 * drop the packet and send an ICMPv6 error message.
			 *
			 * type/code is based on suggestion by Rich Draves.
			 * not sure if it is the best pick.
			 */
			RT_REMREF_LOCKED(rt);	/* Release extra ref */
			RT_UNLOCK(rt);
			icmp6_error(mcopy, ICMP6_DST_UNREACH,
				    ICMP6_DST_UNREACH_ADDR, 0);
			m_freem(m);
			return (NULL);
		}
		type = ND_REDIRECT;
	}

#if IPFW2
	/*
	 * Check with the firewall...
	 */
	if (ip6_fw_enable && ip6_fw_chk_ptr) {
		u_short port = 0;
		ifp = rt->rt_ifp;
		/* Drop the lock but retain the extra ref */
		RT_UNLOCK(rt);
		/* If ipfw says divert, we have to just drop packet */
		if (ip6_fw_chk_ptr(&ip6, ifp, &port, &m)) {
			m_freem(m);
			goto freecopy;
		}
		if (!m) {
			goto freecopy;
		}
		/* We still have the extra ref on rt */
		RT_LOCK(rt);
	}
#endif

	/*
	 * Fake scoped addresses. Note that even link-local source or
	 * destinaion can appear, if the originating node just sends the
	 * packet to us (without address resolution for the destination).
	 * Since both icmp6_error and icmp6_redirect_output fill the embedded
	 * link identifiers, we can do this stuff after making a copy for
	 * returning an error.
	 */
	if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
		/*
		 * See corresponding comments in ip6_output.
		 * XXX: but is it possible that ip6_forward() sends a packet
		 *      to a loopback interface? I don't think so, and thus
		 *      I bark here. ([email protected])
		 * XXX: it is common to route invalid packets to loopback.
		 *	also, the codepath will be visited on use of ::1 in
		 *	rthdr. (itojun)
		 */
#if 1
		if ((0))
#else
		if ((rt->rt_flags & (RTF_BLACKHOLE|RTF_REJECT)) == 0)
#endif
		{
			printf("ip6_forward: outgoing interface is loopback. "
				"src %s, dst %s, nxt %d, rcvif %s, outif %s\n",
				ip6_sprintf(&ip6->ip6_src),
				ip6_sprintf(&ip6->ip6_dst),
				ip6->ip6_nxt, if_name(m->m_pkthdr.rcvif),
				if_name(rt->rt_ifp));
		}

		/* we can just use rcvif in forwarding. */
		origifp = rcvifp = m->m_pkthdr.rcvif;
	} else if (nd6_prproxy) {
		/*
		 * In the prefix proxying case, we need to inform nd6_output()
		 * about the inbound interface, so that any subsequent NS
		 * packets generated by nd6_prproxy_ns_output() will not be
		 * sent back to that same interface.
		 */
		origifp = rcvifp = m->m_pkthdr.rcvif;
	} else {
		rcvifp = m->m_pkthdr.rcvif;
		origifp = rt->rt_ifp;
	}
	/*
	 * clear embedded scope identifiers if necessary.
	 * in6_clearscope will touch the addresses only when necessary.
	 */
	in6_clearscope(&ip6->ip6_src);
	in6_clearscope(&ip6->ip6_dst);

	ifp = rt->rt_ifp;
	/* Drop the lock but retain the extra ref */
	RT_UNLOCK(rt);

	/*
	 * If this is to be processed locally, let ip6_input have it.
	 */
	if (proxy) {
		VERIFY(m->m_pkthdr.pkt_flags & PKTF_PROXY_DST);
		/* Release extra ref */
		RT_REMREF(rt);
		if (mcopy != NULL)
			m_freem(mcopy);
		return (m);
	}

#if PF
	/* Invoke outbound packet filter */
	error = pf_af_hook(ifp, NULL, &m, AF_INET6, FALSE, NULL);

	if (error != 0 || m == NULL) {
		if (m != NULL) {
			panic("%s: unexpected packet %p\n", __func__, m);
			/* NOTREACHED */
		}
		/* Already freed by callee */
		goto senderr;
	}
	ip6 = mtod(m, struct ip6_hdr *);
#endif /* PF */

	/* Mark this packet as being forwarded from another interface */
	m->m_pkthdr.pkt_flags |= PKTF_FORWARDED;
	len = m_pktlen(m);

	error = nd6_output(ifp, origifp, m, dst, rt, NULL);
	if (error) {
		in6_ifstat_inc(ifp, ifs6_out_discard);
		ip6stat.ip6s_cantforward++;
	} else {
		/*
		 * Increment stats on the source interface; the ones
		 * for destination interface has been taken care of
		 * during output above by virtue of PKTF_FORWARDED.
		 */
		rcvifp->if_fpackets++;
		rcvifp->if_fbytes += len;

		ip6stat.ip6s_forward++;
		in6_ifstat_inc(ifp, ifs6_out_forward);
		if (type)
			ip6stat.ip6s_redirectsent++;
		else {
			if (mcopy) {
				goto freecopy;
			}
		}
	}
#if PF
senderr:
#endif /* PF */
	if (mcopy == NULL) {
		/* Release extra ref */
		RT_REMREF(rt);
		return (NULL);
	}
	switch (error) {
	case 0:
#if 1
		if (type == ND_REDIRECT) {
			icmp6_redirect_output(mcopy, rt);
			/* Release extra ref */
			RT_REMREF(rt);
			return (NULL);
		}
#endif
		goto freecopy;

	case EMSGSIZE:
		/* xxx MTU is constant in PPP? */
		goto freecopy;

	case ENOBUFS:
		/* Tell source to slow down like source quench in IP? */
		goto freecopy;

	case ENETUNREACH:	/* shouldn't happen, checked above */
	case EHOSTUNREACH:
	case ENETDOWN:
	case EHOSTDOWN:
	default:
		type = ICMP6_DST_UNREACH;
		code = ICMP6_DST_UNREACH_ADDR;
		break;
	}
	icmp6_error(mcopy, type, code, 0);
	/* Release extra ref */
	RT_REMREF(rt);
	return (NULL);

 freecopy:
	m_freem(mcopy);
	/* Release extra ref */
	RT_REMREF(rt);
	return (NULL);
}
Пример #7
0
	void	adpcm_expand(
		void* out_data_void,
		stream* in,
		int sample_count,	// in stereo, this is number of *pairs* of samples
		bool stereo)
	// Utility function: uncompress ADPCM data from in stream to
	// out_data[].	The output buffer must have (sample_count*2)
	// bytes for mono, or (sample_count*4) bytes for stereo.
	{
		Sint16*	out_data = (Sint16*) out_data_void;

		// Read header.
		int	n_bits = in->read_uint(2) + 2;	// 2 to 5 bits

		while (sample_count)
		{
			// Read initial sample & index values.
			int	sample = in->read_sint(16);

			int	stepsize_index = in->read_uint(6);
			assert(STEPSIZE_CT >= (1 << 6));	// ensure we don't need to clamp.

			int	samples_this_block = imin(sample_count, 4096);
			sample_count -= samples_this_block;

			if (stereo == false)
			{
#define DO_MONO(n) DO_MONO_BLOCK(&out_data, n, samples_this_block, in, sample, stepsize_index)

				switch (n_bits)
				{
				default: assert(0); break;
				case 2: DO_MONO(2); break;
				case 3: DO_MONO(3); break;
				case 4: DO_MONO(4); break;
				case 5: DO_MONO(5); break;
				}
			}
			else
			{
				// Stereo.

				// Got values for left channel; now get initial sample
				// & index for right channel.
				int	right_sample = in->read_sint(16);

				int	right_stepsize_index = in->read_uint(6);
				assert(STEPSIZE_CT >= (1 << 6));	// ensure we don't need to clamp.

#define DO_STEREO(n)					\
	DO_STEREO_BLOCK(				\
		&out_data, n, samples_this_block,	\
		in, sample, stepsize_index,		\
		right_sample, right_stepsize_index)
			
				switch (n_bits)
				{
				default: assert(0); break;
				case 2: DO_STEREO(2); break;
				case 3: DO_STEREO(3); break;
				case 4: DO_STEREO(4); break;
				case 5: DO_STEREO(5); break;
				}
			}
		}
	}
Пример #8
0
dsxc_lutpai (void)

/* C-- */
{
    float  col[3], acol[3], rv;
    int    j, istat, kb[3], kpx, kpy, kbut, js, je,
           kxss, kxse, kpxa;
    Bool   loop, loopmain;
    /* Cbegin */


    DSSNX = F77_NAMED_COMMON(ds_gen).dssnx;

    kxss = 0;
    kxse = DSSNX;
    if ( DSSNX>260 ) {
        kxss = (DSSNX-260)/2;
        kxse = kxss + 260 - 1;
    }

    rv = DSSNX / 2.0;
    (void) dsxc_pscur ( rv, 10.0 );					/* Set cursor at bar centre */

    (void) dsxc_waitbut ( True, False, &kbut, &kpx, &kpy );		/* Buttons up in area? */

    loopmain = True;						/* Loop repeating sequence */
    while ( loopmain ) {

        (void) dsxc_waitbut ( True, True, &kbut, &kpx, &kpy );

        if ( kbut==3 )					/* Exit if button 3 */
            loopmain = False;
        else if ( (kpx<kxss) || (kpx>kxse) )
            (void) c_printo ( "Must be within LUT bar" );
        else {
            rv = (float) (kpx-kxss)/(float) (kxse-kxss+1);
            (void) dsxc_luttran ( rv, col, &je );

            (void) dsxc_waitbut ( True, False, &kbut, &kpx, &kpy );	/* Buttons up in area? */

            (void) dsxc_waitbut ( True, True, &kbut, &kpx, &kpy );	/* Buttons pressed in area? */
            kpx = imin(kxse,imax(kxss,kpx));
            rv = (float) (kpx-kxss)/(float) (kxse-kxss+1);
            kpxa = kpx;
            (void) dsxc_luttran ( rv, acol, &js );

            loop = True;
            while ( loop ) {
                (void) dsxc_getcurpb ( True, &kpx, &kpy, kb, &istat );
                kpx = imin(kxse,imax(kxss,kpx));
                if ( istat==0 ) {
                    if ( (kb[0]==0) && (kb[1]==0) && (kb[2]==0) )
                        loop = False;
                }
                if ( loop && (istat==0) && (kpx>kpxa) ) {
                    rv = (float) (kpx-kxss)/(float) (kxse-kxss+1);
                    (void) dsxc_luttran ( rv, acol, &je );
                    if ( je<js ) {
                        for (j = js-1; j<LVX; j++ ) {
                            LUTC_VAL[j][0] = col[0];
                            LUTC_VAL[j][1] = col[1];
                            LUTC_VAL[j][2] = col[2];
                        }
                        for (j = 0; j<je; j++ ) {
                            LUTC_VAL[j][0] = col[0];
                            LUTC_VAL[j][1] = col[1];
                            LUTC_VAL[j][2] = col[2];
                        }
                    }
                    else {
                        for (j = js-1; j<je; j++ ) {
                            LUTC_VAL[j][0] = col[0];
                            LUTC_VAL[j][1] = col[1];
                            LUTC_VAL[j][2] = col[2];
                        }
                    }
                    (void) dsxc_lutvput();
                    (void) dsxc_lutput ();
                }
            }

        }

    }

    (void) dsxc_lutvput();

    DSCURPOSX = kpx;						/*Store cursor screen posn*/
    DSCURPOSY = kpy;
    DSCURSET = True;

    F77_NAMED_COMMON(ds_gen).dscurposx = kpx;
    F77_NAMED_COMMON(ds_gen).dscurposy = kpy;
    F77_NAMED_COMMON(ds_genb).dscurset = F77_TRUE;


}
Пример #9
0
//-----------------------------------------------------------------
void PaintAll (WinInfo * WI)
{
    int const left    = WI->S.HiddenSide;
    int const width   = WI->S.width;
    int const right   = width - WI->S.HiddenSide;

    int const top     = WI->S.HiddenTop;
    int const bottom  = WI->S.height - WI->S.HiddenBottom;
    int const title_height = mSkin.ncTop;
    int const title_bottom = top + title_height;

    HWND focus;
    int active = 0;

    RECT rc;
    HDC hdc, hdc_win;
    HGDIOBJ hbmpOld;
    StyleItem * pG = 0;
    windowGradients * wG = 0;

    //dbg_printf("painting %x", WI->hwnd);

    active =
        (WI->is_active_app
            && (WI->is_active
                || WI->hwnd == (focus = GetFocus())
                || IsChild(WI->hwnd, focus)
                ))
        || (mSkin.bbsm_option & 1);

    hdc_win = GetWindowDC(WI->hwnd);
    hdc = CreateCompatibleDC(hdc_win);
    WI->buf = CreateCompatibleDC(hdc_win);
    hbmpOld = SelectObject(hdc, CreateCompatibleBitmap(hdc_win, width, title_bottom));

    wG = &mSkin.U + active;

    //----------------------------------
    // Titlebar gradient

    rc.top = top;
    rc.left = left;
    rc.right = right;
    rc.bottom = title_bottom;
    pG = &wG->Title;
    PutGradient(WI, hdc, &rc, pG);

    //----------------------------------
    // Titlebar Buttons

    rc.top = top + mSkin.buttonMargin;
    rc.bottom = rc.top + mSkin.buttonSize;

    LONG w_style = WI->style;
    HICON hico = NULL;
    pG = &wG->Button;

    int label_left = left;
    int label_right = right;
    int barrier = mSkin.labelBarrier !=-1 ? 
        ((right - left) * (mSkin.labelBarrier) / 200) : 0;
    int space = mSkin.buttonMargin;
    int d, i;

    for (d = 1, WI->button_count = i = 0; ; i += d)
    {
        bool state;
        int b;
        struct button_set *p;

        b = mSkin.button_string[i] - '0';
        switch (b) {
            case 0 - '0':
                goto _break;
            case '-' - '0':
                if (d < 0)
                    goto _break;
                d = -1;
                i = strlen(mSkin.button_string);
                space = mSkin.buttonMargin;
                continue;
            case btn_Rollup:
                if (0 == (w_style & WS_SIZEBOX))
                    continue;
                state = WI->is_rolled;
                break;
            case btn_Sticky:
                if ((w_style & WS_CHILD) || 0 == WI->has_sticky)
                    continue;
                state = WI->is_sticky;
                break;
            case btn_OnBG:
                if (w_style & WS_CHILD)
                    continue;
                state = WI->is_onbg;
                break;
            case btn_OnTop:
                if (w_style & WS_CHILD)
                    continue;
                state = WI->is_ontop;
                break;
            case btn_Min:
                if (0 == (w_style & WS_MINIMIZEBOX))
                    continue;
                state = WI->is_iconic;
                break;
            case btn_Max:
                if (0 == (w_style & WS_MAXIMIZEBOX))
                    continue;
                state = WI->is_zoomed;
                break;
            case btn_Close:
                state = false;
                break;
            case btn_Icon:
                if (!get_window_icon(WI->hwnd, &hico))
                    continue;
                state = !active;
                break;
            default:
                continue;
        }

        if (d > 0) // left button
        {
            rc.left = label_left + space;
            label_left = rc.right = rc.left + mSkin.buttonSize;
        }
        else // right button
        {
            rc.right = label_right - space;
            label_right = rc.left = rc.right - mSkin.buttonSize;
        }

        p = &WI->button_set[(int)WI->button_count];
        p->set = b;
        p->pos = rc.left;
        space = mSkin.buttonSpace;

        if (btn_Icon == b)
        {
            int s = mSkin.buttonSize;
            int o = (s - 20)/2;
            if (o < 0)
                o = 0;
            else
                s = 20;
            DrawIconSatnHue(hdc, rc.left+o, rc.top+o, hico, s, s, 0, NULL, DI_NORMAL, state, mSkin.iconSat, mSkin.iconHue);
        }
        else
        {
            int const pressed = WI->button_down == b
                || ((2 & mSkin.bbsm_option) && btn_Close == b);
            DrawButton(WI, hdc, rc, b-1, state, pG + pressed);
        }

        if (++WI->button_count == BUTTON_COUNT)
            _break: break;
    }

    //----------------------------------
    // Titlebar Label gradient

    rc.left = label_left + barrier + (left == label_left ? mSkin.labelMargin : mSkin.buttonInnerMargin);
    rc.right = label_right - barrier - (right == label_right ? mSkin.labelMargin : mSkin.buttonInnerMargin);
    rc.top = top + mSkin.labelMargin;
    rc.bottom = title_bottom - mSkin.labelMargin;

    pG = &wG->Label;
    PutGradient(WI, hdc, &rc, pG);

    //----------------------------------
    // Titlebar Text

    rc.left += mSkin.labelIndent;
    rc.right -= mSkin.labelIndent;

    if (NULL == WI->hFont)
        WI->hFont = CreateFontIndirect(&mSkin.Font);
    HGDIOBJ hfontOld = SelectObject(hdc, WI->hFont);
    SetBkMode(hdc, TRANSPARENT);
    SetTextColor(hdc, pG->TextColor);

    int const title_sz = 192;
    WCHAR wTitle[title_sz];
    wTitle[0] = 0;

    if (WI->is_unicode)
    {
        GetWindowTextW(WI->hwnd, wTitle, title_sz);
        BBDrawTextAltW(hdc, wTitle, -1, &rc,
            mSkin.Justify | DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS | DT_VCENTER,
            pG);
    }
    else
    {
        GetWindowText(WI->hwnd, (char*)wTitle, title_sz);
        BBDrawTextAlt(hdc, (char*)wTitle, -1, &rc,
            mSkin.Justify | DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS | DT_VCENTER,
            pG);
    }

    SelectObject(hdc, hfontOld);

    //----------------------------------
    // Blit the title
    BitBlt(hdc_win, left, top, right-left, title_height, hdc, left, top, SRCCOPY);

    //----------------------------------
    // Frame and Bottom
    if (false == WI->is_iconic
          && (false == WI->is_rolled || (false == mSkin.nixShadeStyle && mSkin.handleHeight)))
    {
        if (int fw = mSkin.frameWidth)
        {
            //----------------------------------
            // Frame left/right(/bottom) border, drawn directly on screen
            rc.top = title_bottom;
            rc.left = left;
            rc.right = right;
            rc.bottom = bottom - WI->S.BottomHeight;
            if (!mSkin.is_style070)
            {
                COLORREF pc = active ? mSkin.F.Title.borderColor : mSkin.U.Title.borderColor;
                HGDIOBJ oldPen = SelectObject(hdc_win, CreatePen(PS_SOLID, 1, pc));
                int const bw = imax(mSkin.F.Title.borderWidth, mSkin.U.Title.borderWidth);
                draw_line(hdc_win, rc.left, rc.left, rc.top, rc.bottom, bw);
                draw_line(hdc_win, rc.right-bw, rc.right-bw, rc.top, rc.bottom, bw);
                DeleteObject(SelectObject(hdc_win, oldPen));
                rc.left += bw;
                rc.right -= bw;
            }

            COLORREF bc = wG->FrameColor;
            HGDIOBJ oldPen = SelectObject(hdc_win, CreatePen(PS_SOLID, 1, bc));
            draw_line(hdc_win, rc.left, rc.left, rc.top, rc.bottom, fw);
            draw_line(hdc_win, rc.right-fw, rc.right-fw, rc.top, rc.bottom, fw);
            if (WI->S.BottomHeight == fw)
                draw_line(hdc_win, rc.left, rc.right, rc.bottom, rc.bottom, fw);
            if (!mSkin.is_style070)
            {
                rc.bottom -= fw;
                draw_line(hdc_win, rc.left, rc.right, rc.top, rc.top, fw);
                draw_line(hdc_win, rc.left, rc.right, rc.bottom, rc.bottom, fw);
            }
            DeleteObject(SelectObject(hdc_win, oldPen));
        }

        if (WI->S.BottomHeight > 0)
        {
            int const gw = mSkin.gripWidth;
            pG = &wG->Handle;
            StyleItem * pG2 = &wG->Grip;
            int const bw = imin(pG->borderWidth, pG2->borderWidth);

            //----------------------------------
            // Bottom Handle gradient
            rc.top = 0;
            rc.bottom = WI->S.BottomHeight;
            rc.left = left;
            rc.right = right;
            if (false == pG2->parentRelative) {
                rc.left += gw - bw;
                rc.right -= gw - bw;
            }
            PutGradient(WI, hdc, &rc, pG);

            //----------------------------------
            // Bottom Grips
            if (false == pG2->parentRelative) {
                rc.right = (rc.left = left) + gw;
                PutGradient(WI, hdc, &rc, pG2);
                rc.left = (rc.right = right) - gw;
                PutGradient(WI, hdc, &rc, pG2);
            }

            //----------------------------------
            // Blit the bottom
            BitBlt(hdc_win, left, bottom - rc.bottom, right-left, rc.bottom, hdc, left, 0, SRCCOPY);

        } // has an handle
    } // not iconic

    DeleteObject(SelectObject(hdc, hbmpOld));
    DeleteDC(hdc);
    DeleteDC(WI->buf);
    ReleaseDC(WI->hwnd, hdc_win);
}
Пример #10
0
/*
 * Send on a socket.
 * If send must go all at once and message is larger than
 * send buffering, then hard error.
 * Lock against other senders.
 * If must go all at once and not enough room now, then
 * inform user that this would block and do nothing.
 * Otherwise, if nonblocking, send as much as possible.
 * The data to be sent is described by "uio" if nonzero,
 * otherwise by the mbuf chain "top" (which must be null
 * if uio is not).  Data provided in mbuf chain must be small
 * enough to send all at once.
 *
 * Returns nonzero on error, timeout or signal; callers
 * must check for short counts if EINTR/ERESTART are returned.
 * Data and control buffers are freed on return.
 */
int
sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
	struct mbuf *top, struct mbuf *control, int flags,
	struct thread *td)
{
	struct mbuf **mp;
	struct mbuf *m;
	size_t resid;
	int space, len;
	int clen = 0, error, dontroute, mlen;
	int atomic = sosendallatonce(so) || top;
	int pru_flags;

	if (uio) {
		resid = uio->uio_resid;
	} else {
		resid = (size_t)top->m_pkthdr.len;
#ifdef INVARIANTS
		len = 0;
		for (m = top; m; m = m->m_next)
			len += m->m_len;
		KKASSERT(top->m_pkthdr.len == len);
#endif
	}

	/*
	 * WARNING!  resid is unsigned, space and len are signed.  space
	 * 	     can wind up negative if the sockbuf is overcommitted.
	 *
	 * Also check to make sure that MSG_EOR isn't used on SOCK_STREAM
	 * type sockets since that's an error.
	 */
	if (so->so_type == SOCK_STREAM && (flags & MSG_EOR)) {
		error = EINVAL;
		goto out;
	}

	dontroute =
	    (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
	    (so->so_proto->pr_flags & PR_ATOMIC);
	if (td->td_lwp != NULL)
		td->td_lwp->lwp_ru.ru_msgsnd++;
	if (control)
		clen = control->m_len;
#define	gotoerr(errcode)	{ error = errcode; goto release; }

restart:
	error = ssb_lock(&so->so_snd, SBLOCKWAIT(flags));
	if (error)
		goto out;

	do {
		if (so->so_state & SS_CANTSENDMORE)
			gotoerr(EPIPE);
		if (so->so_error) {
			error = so->so_error;
			so->so_error = 0;
			goto release;
		}
		if ((so->so_state & SS_ISCONNECTED) == 0) {
			/*
			 * `sendto' and `sendmsg' is allowed on a connection-
			 * based socket if it supports implied connect.
			 * Return ENOTCONN if not connected and no address is
			 * supplied.
			 */
			if ((so->so_proto->pr_flags & PR_CONNREQUIRED) &&
			    (so->so_proto->pr_flags & PR_IMPLOPCL) == 0) {
				if ((so->so_state & SS_ISCONFIRMING) == 0 &&
				    !(resid == 0 && clen != 0))
					gotoerr(ENOTCONN);
			} else if (addr == 0)
			    gotoerr(so->so_proto->pr_flags & PR_CONNREQUIRED ?
				   ENOTCONN : EDESTADDRREQ);
		}
		if ((atomic && resid > so->so_snd.ssb_hiwat) ||
		    clen > so->so_snd.ssb_hiwat) {
			gotoerr(EMSGSIZE);
		}
		space = ssb_space(&so->so_snd);
		if (flags & MSG_OOB)
			space += 1024;
		if ((space < 0 || (size_t)space < resid + clen) && uio &&
		    (atomic || space < so->so_snd.ssb_lowat || space < clen)) {
			if (flags & (MSG_FNONBLOCKING|MSG_DONTWAIT))
				gotoerr(EWOULDBLOCK);
			ssb_unlock(&so->so_snd);
			error = ssb_wait(&so->so_snd);
			if (error)
				goto out;
			goto restart;
		}
		mp = &top;
		space -= clen;
		do {
		    if (uio == NULL) {
			/*
			 * Data is prepackaged in "top".
			 */
			resid = 0;
			if (flags & MSG_EOR)
				top->m_flags |= M_EOR;
		    } else do {
			if (resid > INT_MAX)
				resid = INT_MAX;
			m = m_getl((int)resid, MB_WAIT, MT_DATA,
				   top == NULL ? M_PKTHDR : 0, &mlen);
			if (top == NULL) {
				m->m_pkthdr.len = 0;
				m->m_pkthdr.rcvif = NULL;
			}
			len = imin((int)szmin(mlen, resid), space);
			if (resid < MINCLSIZE) {
				/*
				 * For datagram protocols, leave room
				 * for protocol headers in first mbuf.
				 */
				if (atomic && top == 0 && len < mlen)
					MH_ALIGN(m, len);
			}
			space -= len;
			error = uiomove(mtod(m, caddr_t), (size_t)len, uio);
			resid = uio->uio_resid;
			m->m_len = len;
			*mp = m;
			top->m_pkthdr.len += len;
			if (error)
				goto release;
			mp = &m->m_next;
			if (resid == 0) {
				if (flags & MSG_EOR)
					top->m_flags |= M_EOR;
				break;
			}
		    } while (space > 0 && atomic);
		    if (dontroute)
			    so->so_options |= SO_DONTROUTE;
		    if (flags & MSG_OOB) {
		    	    pru_flags = PRUS_OOB;
		    } else if ((flags & MSG_EOF) &&
		    	       (so->so_proto->pr_flags & PR_IMPLOPCL) &&
			       (resid == 0)) {
			    /*
			     * If the user set MSG_EOF, the protocol
			     * understands this flag and nothing left to
			     * send then use PRU_SEND_EOF instead of PRU_SEND.
			     */
		    	    pru_flags = PRUS_EOF;
		    } else if (resid > 0 && space > 0) {
			    /* If there is more to send, set PRUS_MORETOCOME */
		    	    pru_flags = PRUS_MORETOCOME;
		    } else {
		    	    pru_flags = 0;
		    }
		    /*
		     * XXX all the SS_CANTSENDMORE checks previously
		     * done could be out of date.  We could have recieved
		     * a reset packet in an interrupt or maybe we slept
		     * while doing page faults in uiomove() etc. We could
		     * probably recheck again inside the splnet() protection
		     * here, but there are probably other places that this
		     * also happens.  We must rethink this.
		     */
		    error = so_pru_send(so, pru_flags, top, addr, control, td);
		    if (dontroute)
			    so->so_options &= ~SO_DONTROUTE;
		    clen = 0;
		    control = 0;
		    top = NULL;
		    mp = &top;
		    if (error)
			    goto release;
		} while (resid && space > 0);
	} while (resid);

release:
	ssb_unlock(&so->so_snd);
out:
	if (top)
		m_freem(top);
	if (control)
		m_freem(control);
	return (error);
}
Пример #11
0
char* NextToken(char* buf, const char** string, const char *delims)
{
    const char *a; int n;
    n = nexttoken(&a, string, delims);
    return extract_string(buf, a, imin(n, MAX_PATH - 1));
}
Пример #12
0
float	bt_array::get_sample(int x, int z) const
// Return the altitude from this .bt dataset, at the specified
// coordinates.  x runs west-to-east, and z runs north-to-south,
// unlike UTM.  @@ Fix this to make it match UTM???
//
// Out-of-bounds coordinates are clamped.
{
	// clamp coordinates.
	x = iclamp(x, 0, m_width - 1);
	z = iclamp(z, 0, m_height - 1);

	int	index = 0;
	char*	data = NULL;
	if (m_cache_height) {
		// Cache is active.
		
		// 'v' coordinate is (m_height - 1 - z) -- the issue
		// is that BT scans south-to-north, which our z
		// coordinates run north-to-south.  It's easier to
		// compute cache info using the natural .bt data
		// order.
		int	v = (m_height - 1 - z);

		cache_line*	cl = &m_cache[x];
		if (cl->m_data == NULL || v < cl->m_v0 || v >= cl->m_v0 + m_cache_height) {
			// Cache line must be refreshed.
			cl->m_v0 = (v / m_cache_height) * m_cache_height;
			if (cl->m_data == NULL) {
				cl->m_data = new unsigned char[m_cache_height * m_sizeof_element];
			}
			int	fillsize = imin(m_cache_height, m_height - cl->m_v0) * m_sizeof_element;

			// *** MJH modification: only read from memory mapped file if its around
			if (m_data != NULL)
			{
				memcpy(cl->m_data,
					   ((unsigned char*)m_data) + BT_HEADER_SIZE + (cl->m_v0 + m_height * x) * m_sizeof_element,
					   fillsize);
			}
			else
			{
				// *** MJH modification: else seek and load from the file proper, 64bit addressing
				Uint64 offset_i64 =
					(Uint64) BT_HEADER_SIZE
					+ ((Uint64) cl->m_v0 + (Uint64) m_height * (Uint64) x)
					* (Uint64) m_sizeof_element;
                                lseek64(m_file_handle, offset_i64, SEEK_SET);
				read(m_file_handle, cl->m_data, fillsize);
			}
		}

		index = v - cl->m_v0;
		data = (char*) cl->m_data;
	} else {
		// Cache is inactive.  Index straight into the raw data.
		data = (char*) m_data;
		data += BT_HEADER_SIZE;
		index = (m_height - 1 - z) + m_height * x;
	}

	if (m_float_data) {
		// raw data is floats.
		data += index * 4;
		union {
			float	f;
			Uint32	u;
		} raw;
		raw.u = swap_le32(*(Uint32*) data);

		return raw.f;

	} else {
		// Raw data is 16-bit integer.
		data += index * 2;
		Uint16	y = swap_le16(*(Uint16*) data);

		return y;
	}
}
Пример #13
0
int	main(int argc, char* argv[])
{
	char*	infile = NULL;
	char*	outfile = NULL;
	int	tree_depth = 6;
	int	tile_size = 256;

	for ( int arg = 1; arg < argc; arg++ ) {
		if ( argv[arg][0] == '-' ) {
			// command-line switch.
			
			switch ( argv[arg][1] ) {
			case 'h':
			case '?':
				print_usage();
				exit( 1 );
				break;

			case 't':
				// Set the tilesize.
				if (arg + 1 >= argc) {
					printf("error: -t option requires an integer for tile_size\n");
					print_usage();
					exit(1);
				}
				arg++;
				tile_size = atoi(argv[arg]);
				break;
			case 'd':
				// Tree depth.
				if (arg + 1 >= argc) {
					printf("error: -d option requires an integer for tree_depth\n");
					print_usage();
					exit(1);
				}
				arg++;
				tree_depth = atoi(argv[arg]);
				break;

			default:
				printf("error: unknown command-line switch -%c\n", argv[arg][1]);
				exit(1);
				break;
			}

		} else {
			// File argument.
			if ( infile == NULL ) {
				infile = argv[arg];
			} else if ( outfile == NULL ) {
				outfile = argv[arg];
			} else {
				// This looks like extra noise on the command line; complain and exit.
				printf( "argument '%s' looks like extra noise; exiting.\n", argv[arg]);
				print_usage();
				exit( 1 );
			}
		}
	}

	// Must specify input filename.
	if (infile == NULL) {
		printf("error: you must supply an input filename which points to a .jpg image\n");
		print_usage();
		exit(1);
	}

	// Must specify an output filename.
	if (outfile == NULL) {
		printf("error: you must specify an output filename, for the texture quadtree output\n");
		print_usage();
		exit(1);
	}

	// Validate the tile_size.  Must be a power of two.
	int	logged_tile_size = 1 << frnd(log2((float) tile_size));
	if (tile_size <= 0 || logged_tile_size != tile_size) {
		printf("error: tile_size must be a power of two.\n");
		print_usage();
		exit(1);
	}

	// Validate tree depth.  Keep it within reason.
	if (tree_depth <= 0 || tree_depth > 12)
	{
		printf("error: tree_depth out of range.  Keep it between 1 and 12.\n");
		print_usage();
		exit(1);
	}
	
	// Open input file.
	tu_file*	in = new tu_file(infile, "rb");
	if (in->get_error())
	{
		printf("Can't open input file '%s'!\n", infile);
		delete in;
		exit(1);
	}

	// Open output file.
	tu_file*	out = new tu_file(outfile, "w+b");
	if (out->get_error())
	{
		printf("Can't open output file '%s'!\n", outfile);
		delete in;
		delete out;
		exit(1);
	}

	// Start reading the input.
	jpeg::input*	j_in = jpeg::input::create(in);
	if (j_in == NULL) {
		printf("Failure reading JPEG header of input file '%s'!\n", infile);
		delete in;
		delete out;
		exit(1);
	}

	// Size the tiles.
	int	tile_dim = 1 << (tree_depth - 1);

	// Write .tqt header.
	out->write_bytes("tqt\0", 4);	// filetype tag
	out->write_le32(1);			// version number.
	out->write_le32(tree_depth);
	out->write_le32(tile_size);

	// Make a null table of contents, and write it to the file.
	array<Uint32>	toc;
	toc.resize(tqt::node_count(tree_depth));

	int	toc_start = out->get_position();
	for (int i = 0; i < toc.size(); i++) {
		toc[i] = 0;
		out->write_le32(toc[i]);
	}

	int	tile_max_source_height = int(j_in->get_height() / float(tile_dim) + 1);

	// Create a horizontal strip, as wide as the image, and tall
	// enough to cover a whole tile.
	image::rgb*	strip = image::create_rgb(j_in->get_width(), tile_max_source_height);

	// Initialize the strip by reading the first set of scanlines.
	int	next_scanline = 0;
	int	strip_top = 0;
	while (next_scanline < tile_max_source_height) {
		j_in->read_scanline(image::scanline(strip, next_scanline));
		next_scanline++;
	}

	image::rgb*	tile = image::create_rgb(tile_size, tile_size);

	printf("making leaf tiles....     ");

	// generate base level tiles.
	for (int row = 0; row < tile_dim; row++) {
		float	y0 = float(row) / tile_dim * j_in->get_height();
		float	y1 = float(row + 1) / tile_dim * j_in->get_height();

		int	lines_to_read = imin(int(y1), j_in->get_height()) - (strip_top + strip->m_height);
		if (lines_to_read > 0)
		{
			// Copy existing lines up...
			int	lines_to_keep = strip->m_height - lines_to_read;
			{for (int i = 0; i < lines_to_keep; i++) {
				memcpy(image::scanline(strip, i), image::scanline(strip, i + lines_to_read /*keep*/), strip->m_width * 3);
			}}

			// Read new lines
			{for (int i = lines_to_keep; i < strip->m_height; i++) {
				j_in->read_scanline(image::scanline(strip, i));
			}}

			strip_top += lines_to_read;
		}

		for (int col = 0; col < tile_dim; col++) {
			float	x0 = float(col) / tile_dim * j_in->get_width();
			float	x1 = float(col + 1) / tile_dim * j_in->get_width();

			// Resample from the input strip to the output tile.
			image::resample(tile, 0, 0, tile_size - 1, tile_size - 1,
					strip, x0, y0 - strip_top, x1, y1 - strip_top);

			// Update the table of contents with an offset
			// to the data we're about to write.
			int	offset = out->get_position();
			int	quadtree_index = tqt::node_index(tree_depth - 1, col, row);
			toc[quadtree_index] = offset;

			// Write the jpeg data.
			image::write_jpeg(out, tile, 90);

			int	percent_done = int(100.f * float(col + row * tile_dim) / (tile_dim * tile_dim));
			printf("\b\b\b\b\b\b%3d%% %c", percent_done, spinner[(spin_count++)&3]);
		}
	}


	// Done reading the input file.
	delete j_in;
	delete in;

	delete strip;
	delete tile;	// done with the working tile surface.

	printf("\n");

	printf("making interior tiles....");

	// Now generate the upper levels of the tree by resampling the
	// lower levels.
	// 
	// The output file is both input and output at this point.
	tqt_info	inf(out, &toc, tree_depth, tile_size);
	image::rgb*	root_tile = generate_tiles(&inf, 0, 0, 0);

	delete root_tile;	// dispose of root tile.

	// Write the TOC back into the head of the file.
	out->set_position(toc_start);
	{for (int i = 0; i < toc.size(); i++) {
		out->write_le32(toc[i]);
	}}

	delete out;

	return 0;
}
Пример #14
0
/* Routine to compute eigenvalues */
int plarre(proc_t *procinfo, char *jobz, char *range, in_t *Dstruct, 
	       val_t *Wstruct, tol_t *tolstruct, int *nzp, int *offsetp)
{
  /* input variables */
  int              nproc  = procinfo->nproc;
  bool             wantZ  = (jobz[0]  == 'V' || jobz[0]  == 'v');
  bool             cntval = (jobz[0]  == 'C' || jobz[0]  == 'c');
  int              n      = Dstruct->n;
  double *restrict D      = Dstruct->D;
  double *restrict E      = Dstruct->E;
  int    *restrict isplit = Dstruct->isplit;
  double           *vl    = Wstruct->vl;
  double           *vu    = Wstruct->vu;
  int              *il    = Wstruct->il;
  int              *iu    = Wstruct->iu;
  double *restrict W      = Wstruct->W;
  double *restrict Werr   = Wstruct->Werr;
  double *restrict Wgap   = Wstruct->Wgap;
  int    *restrict Windex = Wstruct->Windex;
  int    *restrict iblock = Wstruct->iblock;
  double *restrict gersch = Wstruct->gersch;

  /* constants */
  int             IZERO = 0,   IONE = 1;
  double          DZERO = 0.0;

  /* work space */
  double          *E2;
  double         *work;
  int             *iwork;

  /* compute geschgorin disks and spectral diameter */
  double          gl, gu, eold, emax, eabs;

  /* compute splitting points */
  int             bl_begin, bl_end, bl_size;

  /* distribute work among processes */
  int             ifirst, ilast, ifirst_tmp, ilast_tmp;
  int             chunk, isize, iil, iiu;

  /* gather results */
  int             *rcount, *rdispl;

  /* others */
  int             info, i, j, jbl, idummy;
  double          tmp1, dummy;
  bool             sorted;
  enum range_enum {allrng=1, valrng=2, indrng=3} irange;
  double          intervals[2];
  int             negcounts[2];
  double          sigma;

  if (range[0] == 'A' || range[0] == 'a') {
    irange = allrng;
  } else if (range[0] == 'V' || range[0] == 'v') {
    irange = valrng;
  } else if (range[0] == 'I' || range[0] == 'i') {
    irange = indrng;
  } else {
    return 1;
  }

  /* allocate work space */
  E2     = (double *) malloc(     n * sizeof(double) );
  assert(E2 != NULL);
  work   = (double *) malloc(   4*n * sizeof(double) );
  assert(work != NULL);
  iwork  = (int *)    malloc(   3*n * sizeof(int) );
  assert(iwork != NULL);
  rcount = (int *)    malloc( nproc * sizeof(int) );
  assert(rcount != NULL);
  rdispl = (int *)    malloc( nproc * sizeof(int) );
  assert(rdispl != NULL);

  /* Compute square of off-diagonal elements */
  for (i=0; i<n-1; i++) {
    E2[i] = E[i]*E[i];
  }

  /* compute geschgorin disks and spectral diameter */
  gl     = D[0];
  gu     = D[0];
  eold   =  0.0;
  emax   =  0.0;
  E[n-1] =  0.0;

  for (i=0; i<n; i++) {
    eabs = fabs(E[i]);
    if (eabs >= emax) emax = eabs;
    tmp1 = eabs + eold;
    gersch[2*i] = D[i] - tmp1;
    gl = fmin(gl, gersch[2*i]);
    gersch[2*i+1] = D[i] + tmp1;
    gu = fmax(gu, gersch[2*i+1]);
    eold = eabs;
  }
  /* min. pivot allowed in the Sturm sequence of T */
  tolstruct->pivmin = DBL_MIN * fmax(1.0, emax*emax);
  /* estimate of spectral diameter */
  Dstruct->spdiam = gu - gl;

  /* compute splitting points with threshold "split" */
  odrra(&n, D, E, E2, &tolstruct->split, &Dstruct->spdiam,
        &Dstruct->nsplit, isplit, &info);
  assert(info == 0);

  if (irange == allrng || irange == indrng) {
    *vl = gl;
    *vu = gu;
  }

  /* set eigenvalue indices in case of all or subset by value has
   * to be computed; thereby convert all problem to subset by index
   * computation */
  if (irange == allrng) {
    *il = 1;
    *iu = n;
  } else if (irange == valrng) {
    intervals[0] = *vl; intervals[1] = *vu;
    
    /* find negcount at boundaries 'vl' and 'vu';
     * needs work of dim(n) and iwork of dim(n) */
    odebz(&IONE, &IZERO, &n, &IONE, &IONE, &IZERO,
  	  &DZERO, &DZERO, &tolstruct->pivmin, D, E, E2, &idummy,
  	  intervals, &dummy, &idummy, negcounts, work, iwork, &info);
    assert(info == 0);
    
    /* update negcounts of whole matrix with negcounts found for block */
    *il = negcounts[0] + 1;
    *iu = negcounts[1];
  }

  if (cntval && irange == valrng) {
    /* clean up and return */
    *nzp = iceil(*iu-*il+1, nproc);
    clean_up_plarre(E2, work, iwork, rcount, rdispl);
    return 0;
  }


  /* loop over unreduced blocks */  
  bl_begin  = 0;
  
  for (jbl=0; jbl<Dstruct->nsplit; jbl++) {
    
    bl_end  = isplit[jbl] - 1;
    bl_size = bl_end - bl_begin + 1;
    
    /* deal with 1x1 block immediately */
    if (bl_size == 1) {
      E[bl_end] = 0.0;
      W[bl_begin]      = D[bl_begin];
      Werr[bl_begin]   = 0.0;
      Werr[bl_begin]   = 0.0;
      iblock[bl_begin] = jbl + 1;
      Windex[bl_begin] = 1;
      bl_begin  = bl_end + 1;
      continue;
    }

    /* Indix range of block */
    iil = 1;
    iiu = bl_size;

    /* each process computes a subset of the eigenvalues of the block */
    ifirst_tmp = iil;
    for (i=0; i<nproc; i++) {
      chunk  = (iiu-iil+1)/nproc + (i < (iiu-iil+1)%nproc);
      if (i == nproc-1) {
	ilast_tmp = iiu;
      } else {
	ilast_tmp = ifirst_tmp + chunk - 1;
	ilast_tmp = imin(ilast_tmp, iiu);
      }
      if (i == procinfo->pid) {
	ifirst    = ifirst_tmp;
	ilast     = ilast_tmp;
	isize     = ilast - ifirst + 1;
	*offsetp = ifirst - iil;
	*nzp      = isize;
      }
      rcount[i]  = ilast_tmp - ifirst_tmp + 1;
      rdispl[i]  = ifirst_tmp - iil;
      ifirst_tmp = ilast_tmp + 1;
      ifirst_tmp = imin(ifirst_tmp, iiu + 1);
    }
    
    /* approximate eigenvalues of input assigned to process */
    if (isize != 0) {      
      info = eigval_approx_proc(procinfo, ifirst, ilast,
				    bl_size, &D[bl_begin], &E[bl_begin], &E2[bl_begin], 
				    &Windex[bl_begin], &iblock[bl_begin], &gersch[2*bl_begin],
				    tolstruct, &W[bl_begin], &Werr[bl_begin], &Wgap[bl_begin], 
				    work, iwork);
      assert(info == 0);    
    }

    /* compute root representation of block */
    info = eigval_root_proc(procinfo, ifirst, ilast,
				  bl_size, &D[bl_begin], &E[bl_begin], &E2[bl_begin], 
				  &Windex[bl_begin], &iblock[bl_begin], &gersch[2*bl_begin],
				  tolstruct, &W[bl_begin], &Werr[bl_begin], &Wgap[bl_begin], 
				  work, iwork);
    assert(info == 0);    

    /* refine eigenvalues assigned to process w.r.t root */
    if (isize != 0) {
      info = eigval_refine_proc(procinfo, ifirst, ilast,
				    bl_size, &D[bl_begin], &E[bl_begin], &E2[bl_begin], 
				    &Windex[bl_begin], &iblock[bl_begin], &gersch[2*bl_begin],
				    tolstruct, &W[bl_begin], &Werr[bl_begin], &Wgap[bl_begin], 
				    work, iwork);
      assert(info == 0);    
    }
    
    memcpy(work, &W[bl_begin], isize * sizeof(double) );
    MPI_Allgatherv(work, isize, MPI_DOUBLE, &W[bl_begin], rcount, rdispl,
		   MPI_DOUBLE, procinfo->comm);
    
    memcpy(work, &Werr[bl_begin], isize * sizeof(double) );
    MPI_Allgatherv(work, isize, MPI_DOUBLE, &Werr[bl_begin], rcount, rdispl,
		   MPI_DOUBLE, procinfo->comm);
    
    memcpy(iwork, &Windex[bl_begin], isize * sizeof(int) );
    MPI_Allgatherv(iwork, isize, MPI_INT, &Windex[bl_begin], rcount, rdispl,
		   MPI_INT, procinfo->comm);
    
    /* Ensure that within block eigenvalues sorted */
    sorted = false;
    while (sorted == false) {
    	sorted = true;
    	for (j=bl_begin; j < bl_end; j++) {
    	  if (W[j+1] < W[j]) {
    	    sorted = false;
    	    tmp1 = W[j];
    	    W[j] = W[j+1];
    	    W[j+1] = tmp1;
    	    tmp1 = Werr[j];
    	    Werr[j] = Werr[j+1];
    	    Werr[j+1] = tmp1;
    	  }
    	}
    }
    
    /* Set indices index correctly */
    for (j=bl_begin; j <= bl_end; j++)
      iblock[j] = jbl + 1;
    
    /* Recompute gaps within the blocks */
    for (j = bl_begin; j < bl_end; j++) {
      Wgap[j] = fmax(0.0, (W[j+1] - Werr[j+1]) - (W[j] + Werr[j]) );
    }
    sigma = E[bl_end];
    Wgap[bl_end] = fmax(0.0, (gu - sigma) - (W[bl_end] + Werr[bl_end]) );

    /* Compute UNSHIFTED eigenvalues */
    if (!wantZ) {
      sigma = E[bl_end];
      for (i=bl_begin; i<=bl_end; i++) {
	W[i]   += sigma;
      }
    }
    
    /* Proceed with next block */
    bl_begin  = bl_end  + 1;
  }
  /* end of loop over unreduced blocks */    
  
  /* free memory */
  clean_up_plarre(E2, work, iwork, rcount, rdispl);
  
  return 0;
}
Пример #15
0
static int
uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr,
    int fflags)
{
	struct uhid_softc *sc = usb_fifo_softc(fifo);
	struct usb_gen_descriptor *ugd;
	uint32_t size;
	int error = 0;
	uint8_t id;

	switch (cmd) {
	case USB_GET_REPORT_DESC:
		ugd = addr;
		if (sc->sc_repdesc_size > ugd->ugd_maxlen) {
			size = ugd->ugd_maxlen;
		} else {
			size = sc->sc_repdesc_size;
		}
		ugd->ugd_actlen = size;
		if (ugd->ugd_data == NULL)
			break;		/* descriptor length only */
		error = copyout(sc->sc_repdesc_ptr, ugd->ugd_data, size);
		break;

	case USB_SET_IMMED:
		if (!(fflags & FREAD)) {
			error = EPERM;
			break;
		}
		if (*(int *)addr) {

			/* do a test read */

			error = uhid_get_report(sc, UHID_INPUT_REPORT,
			    sc->sc_iid, NULL, NULL, sc->sc_isize);
			if (error) {
				break;
			}
			mtx_lock(&sc->sc_mtx);
			sc->sc_flags |= UHID_FLAG_IMMED;
			mtx_unlock(&sc->sc_mtx);
		} else {
			mtx_lock(&sc->sc_mtx);
			sc->sc_flags &= ~UHID_FLAG_IMMED;
			mtx_unlock(&sc->sc_mtx);
		}
		break;

	case USB_GET_REPORT:
		if (!(fflags & FREAD)) {
			error = EPERM;
			break;
		}
		ugd = addr;
		switch (ugd->ugd_report_type) {
		case UHID_INPUT_REPORT:
			size = sc->sc_isize;
			id = sc->sc_iid;
			break;
		case UHID_OUTPUT_REPORT:
			size = sc->sc_osize;
			id = sc->sc_oid;
			break;
		case UHID_FEATURE_REPORT:
			size = sc->sc_fsize;
			id = sc->sc_fid;
			break;
		default:
			return (EINVAL);
		}
		if (id != 0)
			copyin(ugd->ugd_data, &id, 1);
		error = uhid_get_report(sc, ugd->ugd_report_type, id,
		    NULL, ugd->ugd_data, imin(ugd->ugd_maxlen, size));
		break;

	case USB_SET_REPORT:
		if (!(fflags & FWRITE)) {
			error = EPERM;
			break;
		}
		ugd = addr;
		switch (ugd->ugd_report_type) {
		case UHID_INPUT_REPORT:
			size = sc->sc_isize;
			id = sc->sc_iid;
			break;
		case UHID_OUTPUT_REPORT:
			size = sc->sc_osize;
			id = sc->sc_oid;
			break;
		case UHID_FEATURE_REPORT:
			size = sc->sc_fsize;
			id = sc->sc_fid;
			break;
		default:
			return (EINVAL);
		}
		if (id != 0)
			copyin(ugd->ugd_data, &id, 1);
		error = uhid_set_report(sc, ugd->ugd_report_type, id,
		    NULL, ugd->ugd_data, imin(ugd->ugd_maxlen, size));
		break;

	case USB_GET_REPORT_ID:
		*(int *)addr = 0;	/* XXX: we only support reportid 0? */
		break;

	default:
		error = EINVAL;
		break;
	}
	return (error);
}
Пример #16
0
void fft_print_global_fft_mesh(fft_forw_plan plan, double *data, int element, int num)
{
  int i0,i1,i2,b=1;
  int mesh,divide=0,block1=-1,start1;
  int st[3],en[3],si[3];
  int my=-1;
  double tmp;

  for(i1=0;i1<3;i1++) {
    st[i1] = plan.start[i1];
    en[i1] = plan.start[i1]+plan.new_mesh[i1];
    si[i1] = plan.new_mesh[i1];
  }

  mesh = plan.new_mesh[2];
  MPI_Barrier(comm_cart);  
  if(this_node==0) fprintf(stderr,"All: Print Global Mesh: (%d of %d elements)\n",
			   num+1,element);
  MPI_Barrier(comm_cart);
  for(i0=0;i0<n_nodes;i0++) {
    MPI_Barrier(comm_cart);
    if(i0==this_node) fprintf(stderr,"%d: range (%d,%d,%d)-(%d,%d,%d)\n",this_node,st[0],st[1],st[2],en[0],en[1],en[2]);
  }
  MPI_Barrier(comm_cart);
  while(divide==0) {
    if(b*mesh > 7) {
      block1=b;
      divide = (int)ceil(mesh/(double)block1);
    }
    b++;
  }

  for(b=0;b<divide;b++) {
    start1 = b*block1;
    for(i0=mesh-1; i0>=0; i0--) {
      for(i1=start1; i1<imin(start1+block1,mesh);i1++) {
	for(i2=0; i2<mesh;i2++) {
	  if(i0>=st[0] && i0<en[0] && i1>=st[1] && 
	     i1<en[1] && i2>=st[2] && i2<en[2]) my=1;
	  else my=0;
	  MPI_Barrier(comm_cart);
	  if(my==1) {
	   
	    tmp=data[num+(element*((i2-st[2])+si[2]*((i1-st[1])+si[1]*(i0-st[0]))))];
	    if(fabs(tmp)>1.0e-15) {
	      if(tmp<0) fprintf(stderr,"%1.2e",tmp);
	      else      fprintf(stderr," %1.2e",tmp);
	    }
	    else {
	      fprintf(stderr," %1.2e",0.0);
	    }
	  }
	  MPI_Barrier(comm_cart);
	}
	if(my==1) fprintf(stderr," | ");
      }
      if(my==1) fprintf(stderr,"\n");
    }
    if(my==1) fprintf(stderr,"\n");
  }

}
Пример #17
0
/*!
************************************************************************
* \brief
*    decide reference picture reordering, Field only
************************************************************************
*/
void poc_ref_pic_reorder_field(Slice *currSlice, StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no)
{

  VideoParameters *p_Vid = currSlice->p_Vid;
  //InputParameters *p_Inp = currSlice->p_Inp;
  StorablePicture *p_Enc_Pic = p_Vid->enc_picture;
  DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;

  unsigned int i,j,k;

  int currPicNum, picNumLXPred;

  int default_order[32];
  int re_order[32];
  int tmp_reorder[32];
  int list_sign[32];  
  int poc_diff[32];
  int fld_type[32];

  int reorder_stop, no_reorder;
  int tmp_value, diff;

  int abs_poc_dist;
  int maxPicNum;
  unsigned int num_refs;

  int field_used[2] = {1, 2};
  int fld, idx, num_flds;

  unsigned int top_idx = 0;
  unsigned int bot_idx = 0;
  unsigned int list_size = 0;

  StorablePicture *pField[2]; // 0: TOP_FIELD, 1: BOTTOM_FIELD
  FrameStore      *pFrameStore; 

  maxPicNum  = 2 * p_Vid->max_frame_num;
  currPicNum = 2 * p_Vid->frame_num + 1;

  picNumLXPred = currPicNum;

  // First assign default list order.
  for (i=0; i<num_ref_idx_lX_active; i++)
  {
    default_order[i] = list[i]->pic_num;
  }

  // Now access all references in buffer and assign them
  // to a potential reordering list. For each one of these
  // references compute the poc distance compared to current
  // frame.  
  // look for eligible fields
  idx = 0;

  for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
  {
    pFrameStore = p_Dpb->fs_ref[i];
    pField[0]   = pFrameStore->top_field;
    pField[1]   = pFrameStore->bottom_field;
    num_flds    = (currSlice->structure == BOTTOM_FIELD && (p_Enc_Pic->poc == (pField[0]->poc + 1) ) ) ? 1 : 2;

    poc_diff[2*i    ] = 0xFFFF;
    poc_diff[2*i + 1] = 0xFFFF;

    for ( fld = 0; fld < num_flds; fld++ )
    {
#if (MVC_EXTENSION_ENABLE)
      if ( (pFrameStore->is_used & field_used[fld]) && pField[fld]->used_for_reference && !(pField[fld]->is_long_term) 
        && (p_Vid->p_Inp->num_of_views==1 || pField[fld]->view_id==p_Vid->view_id))
#else
      if ( (pFrameStore->is_used & field_used[fld]) && pField[fld]->used_for_reference && !(pField[fld]->is_long_term))
#endif
      {
        abs_poc_dist = iabs(pField[fld]->poc - p_Enc_Pic->poc) ;
        poc_diff[idx] = abs_poc_dist;
        re_order[idx] = pField[fld]->pic_num;
        fld_type[idx] = fld + 1;

        if (list_no == LIST_0)
        {
          list_sign[idx] = (p_Enc_Pic->poc < pField[fld]->poc) ? +1 : -1;
        }
        else
        {
          list_sign[idx] = (p_Enc_Pic->poc > pField[fld]->poc) ? +1 : -1;
        }
        idx++;
      }
    }
  }
  num_refs = idx;

  // now sort these references based on poc (temporal) distance
  for (i=0; i < num_refs-1; i++)
  {
    for (j = (i + 1); j < num_refs; j++)
    {
      if (poc_diff[i] > poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
      {
        // poc_diff
        tmp_value   = poc_diff[i];
        poc_diff[i] = poc_diff[j];
        poc_diff[j] = tmp_value;
        // re_order (PicNum)
        tmp_value   = re_order[i];
        re_order[i] = re_order[j];
        re_order[j] = tmp_value;
        // list_sign
        tmp_value    = list_sign[i];
        list_sign[i] = list_sign[j];
        list_sign[j] = tmp_value;
        // fld_type
        tmp_value   = fld_type[i];
        fld_type[i] = fld_type[j];
        fld_type[j] = tmp_value ;
      }
    }
  }

  if (currSlice->structure == TOP_FIELD)
  {
    while ((top_idx < num_refs)||(bot_idx < num_refs))
    {
      for ( ; top_idx < num_refs; top_idx++)
      {
        if ( fld_type[top_idx] == TOP_FIELD )
        {
          tmp_reorder[list_size] = re_order[top_idx];
          list_size++;
          top_idx++;
          break;
        }
      }
      for ( ; bot_idx < num_refs; bot_idx++)
      {
        if ( fld_type[bot_idx] == BOTTOM_FIELD )
        {
          tmp_reorder[list_size] = re_order[bot_idx];
          list_size++;
          bot_idx++;
          break;
        }
      }
    }
  }
  if (currSlice->structure == BOTTOM_FIELD)
  {
    while ((top_idx < num_refs)||(bot_idx < num_refs))
    {
      for ( ; bot_idx < num_refs; bot_idx++)
      {
        if ( fld_type[bot_idx] == BOTTOM_FIELD )
        {
          tmp_reorder[list_size] = re_order[bot_idx];
          list_size++;
          bot_idx++;
          break;
        }
      }
      for ( ; top_idx < num_refs; top_idx++)
      {
        if ( fld_type[top_idx] == TOP_FIELD )
        {
          tmp_reorder[list_size] = re_order[top_idx];
          list_size++;
          top_idx++;
          break;
        }
      }
    }
  }

  // copy to final matrix
  list_size = imin( list_size, 32 );
  for ( i = 0; i < list_size; i++ )
  {
    re_order[i] = tmp_reorder[i];
  }

  // Check versus default list to see if any
  // change has happened
  no_reorder = 1;
  for (i=0; i<num_ref_idx_lX_active; i++)
  {
    if (default_order[i] != re_order[i])
    {
      no_reorder = 0;
    }
  }

  // If different, then signal reordering
  if (no_reorder == 0)
  {
    for (i=0; i<num_ref_idx_lX_active; i++)
    {
      diff = re_order[i] - picNumLXPred;
      if (diff <= 0)
      {
        reordering_of_pic_nums_idc[i] = 0;
        abs_diff_pic_num_minus1[i] = iabs(diff)-1;
        if (abs_diff_pic_num_minus1[i] < 0)
          abs_diff_pic_num_minus1[i] = maxPicNum -1;
      }
      else
      {
        reordering_of_pic_nums_idc[i] = 1;
        abs_diff_pic_num_minus1[i] = iabs(diff)-1;
      }
      picNumLXPred = re_order[i];

      tmp_reorder[i] = re_order[i];

      k = i;
      for (j = i; j < num_ref_idx_lX_active; j++)
      {
        if (default_order[j] != re_order[i])
        {
          ++k;
          tmp_reorder[k] = default_order[j];
        }
      }
      reorder_stop = 1;
      for(j=i+1; j<num_ref_idx_lX_active; j++)
      {
        if (tmp_reorder[j] != re_order[j])
        {
          reorder_stop = 0;
          break;
        }
      }

      if (reorder_stop==1)
      {
        ++i;
        break;
      }

      memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
    }
    reordering_of_pic_nums_idc[i] = 3;

    memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));

    if (list_no==0)
    {
      currSlice->ref_pic_list_reordering_flag[LIST_0] = 1;
    }
    else
    {
      currSlice->ref_pic_list_reordering_flag[LIST_1] = 1;
    }
  }
}
Пример #18
0
/* 
 * Assign the computation of eigenvectors to the processes
 */
static  
int assign_to_proc
(proc_t *procinfo, in_t *Dstruct, val_t *Wstruct,
 vec_t *Zstruct, int *nzp, int *myfirstp)
{
  /* From inputs */
  int              pid     = procinfo->pid;
  int              nproc   = procinfo->nproc;
  double *restrict L       = Dstruct->E;
  int    *restrict isplit  = Dstruct->isplit;
  int              n       = Wstruct->n;
  int              il      = *(Wstruct->il);
  int              iu      = *(Wstruct->iu);
  double *restrict W       = Wstruct->W;
  int    *restrict Windex  = Wstruct->Windex;
  int    *restrict iblock  = Wstruct->iblock;
  int    *restrict iproc   = Wstruct->iproc;
  int    *restrict Zindex  = Zstruct->Zindex;
  
  sort_struct_t *array = (sort_struct_t *) malloc(n*sizeof(sort_struct_t));
  
  int i;
  for (i=0; i<n; i++) {
    /* Find shift of block */
    int iblk = iblock[i];
    int ishift  = isplit[iblk-1] - 1;
    /* Apply shift so that unshifted eigenvalues can be sorted */
    array[i].lambda    = W[i] + L[ishift]; 
    array[i].local_ind = Windex[i];
    array[i].block_ind = iblk;
    array[i].ind       = i;
  }
  /* Alternatively could sort list of pointers, which
     requires less data copying */

  qsort(array, n, sizeof(sort_struct_t), cmpa);

  /* Mark eigenvectors that do not need to be computed */
  int j;
  for (j = 0; j < il-1; j++ ) {
    iproc[array[j].ind]  = -1;
    Zindex[array[j].ind] = -1;
  }

  int isize = iu - il + 1;

  int ibegin=il-1, iend;
  int id;
  for (id=0; id<nproc; id++) {

    int chunk = imax(1, isize/nproc + (id < isize%nproc));
    
    if (id==nproc-1) {
      iend = iu - 1;
    } else {
      iend = ibegin + chunk - 1;
      iend = imin(iend, iu -1);
    }

    int k = 0;
    for (j=ibegin; j<=iend; j++) {
      iproc[array[j].ind]  = id;
      Zindex[array[j].ind] = k;
      k++;
    }

    if (id == pid) {
      *myfirstp   = ibegin - il + 1;
      *nzp        = iend - ibegin + 1;
      Zstruct->nz = *nzp; 
    }

    ibegin = iend + 1;
    ibegin = imin(ibegin, iu);
  } /* end id */

  for (j = iend+1; j < n; j++ ) {
    iproc[array[j].ind]  = -1;
    Zindex[array[j].ind] = -1;
  }
  
  free(array);
  return 0;
}
Пример #19
0
	void	as_s_function::operator()(const fn_call& fn)
	// Dispatch.
	{

		assert(fn.env);

		// Keep target alive during execution!
		gc_ptr<as_object> target(m_target.get_ptr());

		// try to use caller environment
		// if the caller object has own environment then we use its environment
		as_environment* env = fn.env;
		if (fn.this_ptr)
		{
			if (fn.this_ptr->get_environment())
			{
				env = fn.this_ptr->get_environment();
			}
		}

		// set 'this'
		as_object* this_ptr = env->get_target();
		if (fn.this_ptr)
		{
			this_ptr = fn.this_ptr;
			if (this_ptr->m_this_ptr != NULL)
			{
				this_ptr = this_ptr->m_this_ptr.get_ptr();
			}
		}

		// Function has been declared in moviclip ==> we should use its environment
		// At the same time 'this_ptr' may refers to another object
		// see testcase in .h file
		if (m_target != NULL)
		{
			character* ch = cast_to<character>(m_target.get_ptr());
			if (ch)
			{
				if (ch->is_alive())
				{
					env = m_target->get_environment();
				}
			}
		}

		// Set up local stack frame, for parameters and locals.
		int	local_stack_top = env->get_local_frame_top();
		env->add_frame_barrier();

		if (m_is_function2 == false)
		{
			// Conventional function.

			// Push the arguments onto the local frame.
			int	args_to_pass = imin(fn.nargs, m_args.size());
			for (int i = 0; i < args_to_pass; i++)
			{
				assert(m_args[i].m_register == 0);
				env->add_local(m_args[i].m_name, fn.arg(i));
			}

			env->set_local("this", this_ptr);

			// Put 'super' in a local var.
			if (fn.this_ptr)
			{
				env->add_local("super", fn.this_ptr->get_proto());
			}
		}
		else
		{
			// function2: most args go in registers; any others get pushed.
			
			// Create local registers.
			env->add_local_registers(m_local_register_count);

			// Handle the explicit args.
			int	args_to_pass = imin(fn.nargs, m_args.size());
			for (int i = 0; i < args_to_pass; i++)
			{
				if (m_args[i].m_register == 0)
				{
					// Conventional arg passing: create a local var.
					env->add_local(m_args[i].m_name, fn.arg(i));
				}
				else
				{
					// Pass argument into a register.
					int	reg = m_args[i].m_register;
					env->set_register(reg, fn.arg(i));
				}
			}

			// Handle the implicit args.
			int	current_reg = 1;

			if (m_function2_flags & 0x01)
			{
				// preload 'this' into a register.
				IF_VERBOSE_ACTION(log_msg("-------------- preload this=%p to register %d\n",
					this_ptr, current_reg));
				env->set_register(current_reg, this_ptr);
				current_reg++;

			}

			if (m_function2_flags & 0x02)
			{
				// Don't put 'this' into a local var.
			}
			else
			{
				// Put 'this' in a local var.
				env->add_local("this", as_value(this_ptr));
			}

			// Init arguments array, if it's going to be needed.
			gc_ptr<as_array>	arg_array;
			if ((m_function2_flags & 0x04) || ! (m_function2_flags & 0x08))
			{
				arg_array = new as_array(env->get_player());

				as_value	index_number;
				for (int i = 0; i < fn.nargs; i++)
				{
					index_number.set_int(i);
					arg_array->set_member(index_number.to_string(), fn.arg(i));
				}
			}

			if (m_function2_flags & 0x04)
			{
				// preload 'arguments' into a register.
				env->set_register(current_reg, arg_array.get_ptr());
				current_reg++;
			}

			if (m_function2_flags & 0x08)
			{
				// Don't put 'arguments' in a local var.
			}
			else
			{
				// Put 'arguments' in a local var.
 				env->add_local("arguments", as_value(arg_array.get_ptr()));
			}

			if (m_function2_flags & 0x10)
			{
				// Put 'super' in a register.
				IF_VERBOSE_ACTION(log_msg("-------------- preload super=%p to register %d\n",
					fn.this_ptr->get_proto(), current_reg));
				env->set_register(current_reg, fn.this_ptr->get_proto());
				current_reg++;
			}

			if (m_function2_flags & 0x20)
			{
				// Don't put 'super' in a local var.
			}
			else
			{
				// Put 'super' in a local var.
				env->add_local("super", fn.this_ptr->get_proto());
			}

			if (m_function2_flags & 0x40)
			{
				// Put '_root' in a register.
				env->set_register(current_reg, env->get_root()->get_root_movie());
				current_reg++;
			}

			if (m_function2_flags & 0x80)
			{
				// Put '_parent' in a register.
				array<with_stack_entry>	dummy;
				as_value	parent = env->get_variable("_parent", dummy);
				IF_VERBOSE_ACTION(log_msg("-------------- preload _parent=%p to register %d\n", parent.to_object(), current_reg));
				env->set_register(current_reg, parent);
				current_reg++;
			}

			if (m_function2_flags & 0x100)
			{
				// Put '_global' in a register.
				IF_VERBOSE_ACTION(log_msg("-------------- preload _global=%p to register %d\n", 
					get_global(), current_reg));
				env->set_register(current_reg, get_global());
				current_reg++;
			}
		}

		// keep stack size
		int stack_size = env->get_stack_size();

		// Execute the actions.
		m_action_buffer.execute(env, m_start_pc, m_length, fn.result, m_with_stack, m_is_function2);

		// restore stack size
		// it should not be but it happens
		if (stack_size != env->get_stack_size())
		{
//			log_error("s_function: on entry stack size (%d) != on exit stack size (%d)\n", 
//				stack_size, env->m_stack.size());
			env->set_stack_size(stack_size);
		}

		// Clean up stack frame.
		env->set_local_frame_top(local_stack_top);

		if (m_is_function2)
		{
			// Clean up the local registers.
			env->drop_local_registers(m_local_register_count);
		}
				
	}
Пример #20
0
/*
 * Initialize work queue by putting all tasks for the process
 * into the work queue.
 */
static 
int init_workQ
(proc_t *procinfo, in_t *Dstruct, val_t *Wstruct, int *nzp, workQ_t *workQ)
{
  int              pid      = procinfo->pid;
  int              nproc    = procinfo->nproc;
  int              nthreads = procinfo->nthreads;
  double *restrict D        = Dstruct->D;
  double *restrict L        = Dstruct->E;
  int              nsplit   = Dstruct->nsplit;
  int    *restrict isplit   = Dstruct->isplit;
  double *restrict W        = Wstruct->W;
  double *restrict Werr     = Wstruct->Werr;
  double *restrict Wgap     = Wstruct->Wgap;
  int    *restrict iproc    = Wstruct->iproc;
  double *restrict Wshifted = Wstruct->Wshifted;
  double *restrict gersch   = Wstruct->gersch;
  int              nz       = *nzp;

  /* Loop over blocks */
  int i, j, k, l;
  int ibegin  = 0;
  for ( j=0; j<nsplit; j++ ) {
    int iend = isplit[j] - 1;
    int isize = iend - ibegin + 1;
    double sigma = L[iend];

    /* Use Gerschgorin disks to find spectral diameter */
    double gl = gersch[2*ibegin    ];
    double gu = gersch[2*ibegin + 1];
    for (i=ibegin+1; i<iend; i++) {
      gl = fmin(gl, gersch[2*i    ]);
      gu = fmax(gu, gersch[2*i + 1]);
    }
    double spdiam = gu - gl;
    double avggap = spdiam / (isize-1);

    /* Find eigenvalues in block */
    int nbl = 0;
    int iWbegin = iend   + 1;
    int iWend   = ibegin - 1;
    for (i=ibegin; i<=iend; i++) {
      if (nbl == 0 && iproc[i] == pid) {
        iWbegin = i;
        iWend   = i;
        nbl++;
        k = i+1;
        while (k <=iend && iproc[k] == pid) {
          iWend++;
          nbl++;
          k++;
        }
        /* iWend = iWbegin + nbl - 1; instead of incrementing in loop */
      }
    }

    /* If no eigenvalues for process in block continue */
    if (nbl == 0) {
      ibegin = iend + 1;
      continue;
    }

    /* Compute DL and DLL for later computation of singletons
     * (freed when all singletons of root are computed) */
    double *DL = (double*)malloc(isize*sizeof(double));
    assert(DL != NULL);
    
    double *DLL = (double*)malloc(isize*sizeof(double));
    assert(DLL != NULL);

    for (i=0; i<isize-1; i++) {
      double tmp = D[i+ibegin]*L[i+ibegin];
      DL[i]      = tmp;
      DLL[i]     = tmp*L[i+ibegin];
    }

    rrr_t *RRR = PMR_create_rrr(&D[ibegin], &L[ibegin], DL, DLL, isize, 0);
    PMR_increment_rrr_dependencies(RRR);
    
    /* In W apply shift of current block to eigenvalues
     * to get unshifted values w.r.t. T */
    for (i=ibegin; i<=iend; i++)
      W[i] += sigma;

    /* Split eigenvalues of block into singletons and clusters
     * and add them to process work queue */
    int max_size = imax(1, nz/nthreads);
    bool task_inserted = false;
    int new_first=ibegin, new_last;
    int sn_first, sn_last, sn_size;
    for (i=ibegin; i<=iend; i++) {
      if (i == iend)
        new_last = i;
      else if (Wgap[i] >= MIN_RELGAP*fabs(Wshifted[i]))
        new_last = i;
      else
        continue;

      /* Skip rest if no eigenvalues of process */
      if (new_first > iWend || new_last < iWbegin) {
        new_first = i + 1;
        continue;
      }

      int new_size = new_last - new_first + 1;
      
      if (new_size == 1) {
        /* Singleton was found */
        if (new_first < iWbegin || new_first > iWend) {
          new_first = i + 1;
          continue;
        } else {
          if (new_first==iWbegin || task_inserted==true) {
            /* Initialize new singleton task */
            sn_first = new_first;
            sn_last  = new_first;
            sn_size  = 1;
          } else {
            /* Extend singleton task by one */
            sn_last++;
            sn_size++;
          }
        }

        /* Insert task if ... */
        if (i==iWend || sn_size>=max_size ||
            Wgap[i+1] < MIN_RELGAP*fabs(Wshifted[i+1])) {

          double lgap;
          if (sn_first == ibegin) {
            lgap = fmax(0.0, W[ibegin] - Werr[ibegin] - gl );
          } else {
            lgap = Wgap[sn_first-1];
          }

          PMR_increment_rrr_dependencies(RRR);

          task_t *task = 
            PMR_create_s_task
            (sn_first, sn_last, 1, ibegin, iend, spdiam, lgap, RRR);
          
          PMR_insert_task_at_back(workQ->s_queue, task);
          
          task_inserted = true;
        } else {
          task_inserted = false;
        }
      } else {
        /* Cluster was found */
        int cl_first = new_first;
        int cl_last  = new_last;
        int cl_size  = new_size;

        /* Split cluster into clusters by absolut criterion */
        if (cl_size > 3) {
          /* Split cluster to smaller clusters [cl_first:cl_last] */
          for (k=new_first+1; k<new_last; k++) {
            if (k == new_last-1)
              cl_last = new_last;
            else if (k != cl_first && Wgap[k] > 0.8*avggap)
              cl_last = k;
            else
              continue;

            /* Skip cluster if no eigenvalues of process in it */
            if (cl_last < iWbegin || cl_first > iWend) {
              cl_first = k + 1;
              continue;
            }

            /* Record left gap of cluster */
            double lgap;
            if (cl_first == ibegin) {
              lgap = fmax(0.0, W[ibegin] - Werr[ibegin] - gl);
            } else {
              lgap = Wgap[cl_first-1];
            }

            /* Determine processes involved in processing the cluster */
            int left_pid  = nproc-1;
            int right_pid = 0;
            for (l=cl_first; l<=cl_last; l++) {
              if (iproc[l] != -1) {
                left_pid  = imin(left_pid,  iproc[l]);
                right_pid = imax(right_pid, iproc[l]);
              }
            }

            rrr_t *RRR_parent = 
              PMR_create_rrr(&D[ibegin], &L[ibegin], NULL, NULL, isize, 0);

            task_t *task = 
              PMR_create_c_task
              (cl_first, cl_last, 1, ibegin, iend, spdiam, lgap, iWbegin, 
               iWend, left_pid, right_pid, RRR_parent);

            /* Insert task into queue, depending if cluster need
             * communication with other processes */
            if (left_pid != right_pid)
              PMR_insert_task_at_back(workQ->r_queue, task);
            else
              PMR_insert_task_at_back(workQ->c_queue, task);
            
            cl_first = k + 1;
          } /* end k */
        } else {
          /* Cluster is too small to split, so insert it to queue */

          /* Record left gap of cluster */
          double lgap;
          if (cl_first == ibegin) {
            lgap = fmax(0.0, W[ibegin] - Werr[ibegin] - gl );
          } else {
            lgap = Wgap[cl_first-1];
          }

          /* Determine processes involved */
          int left_pid  = nproc-1;
          int right_pid = 0;
          for (l=cl_first; l<=cl_last; l++) {
            if (iproc[l] != -1) {
              left_pid  = imin(left_pid,  iproc[l]);
              right_pid = imax(right_pid, iproc[l]);
            }
          }

          rrr_t *RRR_parent = 
            PMR_create_rrr
            (&D[ibegin], &L[ibegin], NULL, NULL, isize, 0);

          task_t *task = 
            PMR_create_c_task
            (cl_first, cl_last, 1, ibegin, 
             iend, spdiam, lgap, iWbegin, iWend,
             left_pid, right_pid, RRR_parent);

          /* Insert task into queue, depending if cluster need
           * communication with other processes */
          if (left_pid != right_pid)
            PMR_insert_task_at_back(workQ->r_queue, task);
          else
            PMR_insert_task_at_back(workQ->c_queue, task);
        }
        task_inserted = true;
      } /* end new_size */

      new_first = i + 1;
    } /* end of splitting eigenvalues into tasks */

    /* Set flag in RRR that last singleton is created */
    PMR_set_parent_processed_flag(RRR);
    PMR_try_destroy_rrr(RRR);

    ibegin = iend + 1;
  } /* end loop over blocks */ 

  return 0;
}
Пример #21
0
/*!
************************************************************************
* \brief
*    Initialize reference lists for a P Slice
*
************************************************************************
*/
void init_lists_p_slice_mvc(Slice *currSlice)
{
  VideoParameters *p_Vid = currSlice->p_Vid;
  DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;

  unsigned int i;

  int list0idx = 0;
  int listltidx = 0;

  FrameStore **fs_list0;
  FrameStore **fs_listlt;

  int currPOC = currSlice->ThisPOC;
  int curr_view_id = currSlice->view_id;
  int anchor_pic_flag = currSlice->anchor_pic_flag;

  currSlice->listinterviewidx0 = 0;
  currSlice->listinterviewidx1 = 0;

  if (currSlice->structure == FRAME)
  {
    for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
    {
      if (p_Dpb->fs_ref[i]->is_used==3)
      {
        if ((p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Dpb->fs_ref[i]->frame->is_long_term) && (p_Dpb->fs_ref[i]->frame->view_id == curr_view_id))
        {
          currSlice->listX[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
        }
      }
    }
    // order list 0 by PicNum
    qsort((void *)currSlice->listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
    currSlice->listXsize[0] = (char) list0idx;
    //printf("listX[0] (PicNum): "); for (i=0; i<list0idx; i++){printf ("%d  ", currSlice->listX[0][i]->pic_num);} printf("\n");

    // long term handling
    for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
    {
      if (p_Dpb->fs_ltref[i]->is_used==3)
      {
        if (p_Dpb->fs_ltref[i]->frame->is_long_term && (p_Dpb->fs_ltref[i]->frame->view_id == curr_view_id))
        {
          currSlice->listX[0][list0idx++]=p_Dpb->fs_ltref[i]->frame;
        }
      }
    }
    qsort((void *)&currSlice->listX[0][(short) currSlice->listXsize[0]], list0idx - currSlice->listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
    currSlice->listXsize[0] = (char) list0idx;
  }
  else
  {
    fs_list0 = calloc(p_Dpb->size, sizeof (FrameStore*));
    if (NULL==fs_list0)
      no_mem_exit("init_lists: fs_list0");
    fs_listlt = calloc(p_Dpb->size, sizeof (FrameStore*));
    if (NULL==fs_listlt)
      no_mem_exit("init_lists: fs_listlt");

    for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
    {
      if (p_Dpb->fs_ref[i]->is_reference && (p_Dpb->fs_ref[i]->view_id == curr_view_id))
      {
        fs_list0[list0idx++] = p_Dpb->fs_ref[i];
      }
    }

    qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_frame_num_desc);

    //printf("fs_list0 (FrameNum): "); for (i=0; i<list0idx; i++){printf ("%d  ", fs_list0[i]->frame_num_wrap);} printf("\n");

    currSlice->listXsize[0] = 0;
    gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listX[0], &currSlice->listXsize[0], 0);

    //printf("listX[0] (PicNum): "); for (i=0; i < currSlice->listXsize[0]; i++){printf ("%d  ", currSlice->listX[0][i]->pic_num);} printf("\n");

    // long term handling
    for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
    {
      if (p_Dpb->fs_ltref[i]->view_id == curr_view_id)
        fs_listlt[listltidx++]=p_Dpb->fs_ltref[i];
    }

    qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);

    gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listX[0], &currSlice->listXsize[0], 1);

    free(fs_list0);
    free(fs_listlt);
  }
  currSlice->listXsize[1] = 0;    

  if (currSlice->svc_extension_flag == 0)
  {        
    currSlice->fs_listinterview0 = calloc(p_Dpb->size, sizeof (FrameStore*));
    if (NULL==currSlice->fs_listinterview0)
      no_mem_exit("init_lists: fs_listinterview0");
    list0idx = currSlice->listXsize[0];
    if (currSlice->structure == FRAME)
    {	
      append_interview_list(p_Dpb, 0, 0, currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_view_id, anchor_pic_flag);

      for (i=0; i<(unsigned int)currSlice->listinterviewidx0; i++)
      {
        currSlice->listX[0][list0idx++]=currSlice->fs_listinterview0[i]->frame;
      }
      currSlice->listXsize[0] = (char) list0idx;
    }
    else
    {
      append_interview_list(p_Dpb, currSlice->structure, 0, currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_view_id, anchor_pic_flag);
      gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0, currSlice->listinterviewidx0, currSlice->listX[0], &currSlice->listXsize[0]);
    }
  }

  // set max size
  currSlice->listXsize[0] = (char) imin (currSlice->listXsize[0], currSlice->num_ref_idx_active[LIST_0]);
  currSlice->listXsize[1] = (char) imin (currSlice->listXsize[1], currSlice->num_ref_idx_active[LIST_1]);

  // set the unused list entries to NULL
  for (i=currSlice->listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
  {
    currSlice->listX[0][i] = p_Vid->no_reference_picture;
  }
  for (i=currSlice->listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
  {
    currSlice->listX[1][i] = p_Vid->no_reference_picture;
  }
/*#if PRINTREFLIST  
  // print out for debug purpose
  if((p_Vid->profile_idc == MVC_HIGH || p_Vid->profile_idc == STEREO_HIGH) && currSlice->current_slice_nr==0)
  {
    if(currSlice->listXsize[0]>0)
    {
      printf("\n");
      printf(" ** (CurViewID:%d) %s Ref Pic List 0 ****\n", currSlice->view_id, currSlice->structure==FRAME ? "FRM":(currSlice->structure==TOP_FIELD ? "TOP":"BOT"));
      for(i=0; i<(unsigned int)(currSlice->listXsize[0]); i++)	//ref list 0
      {
        printf("   %2d -> POC: %4d PicNum: %4d ViewID: %d\n", i, currSlice->listX[0][i]->poc, currSlice->listX[0][i]->pic_num, currSlice->listX[0][i]->view_id);
      }
    }
  }
#endif*/
}
Пример #22
0
/* detach an object from a superior object */
void
detachobject(struct vinum_ioctl_msg *msg)
{
    struct _ioctl_reply *reply = (struct _ioctl_reply *) msg;
    struct sd *sd;
    struct plex *plex;
    struct volume *vol;
    int sdno;
    int plexno;

    switch (msg->type) {
    case drive_object:					    /* you can't detach a drive from anything */
    case volume_object:					    /* nor a volume */
    case invalid_object:				    /* "this can't happen" */
	reply->error = EINVAL;
	reply->msg[0] = '\0';				    /* vinum(8) doesn't do this */
	return;

    case sd_object:
	sd = validsd(msg->index, reply);
	if (sd == NULL)
	    return;
	if (sd->plexno < 0) {				    /* doesn't belong to a plex */
	    reply->error = ENOENT;
	    strcpy(reply->msg, "Subdisk is not attached");
	    return;
	} else {					    /* valid plex number */
	    plex = &PLEX[sd->plexno];
	    if ((!msg->force)				    /* don't force things */
	    &&((plex->state == plex_up)			    /* and the plex is up */
	    ||((plex->state == plex_flaky) && sd->state == sd_up))) { /* or flaky with this sd up */
		reply->error = EBUSY;			    /* we need this sd */
		reply->msg[0] = '\0';
		return;
	    }
	    sd->plexno = -1;				    /* anonymous sd */
	    if (plex->subdisks == 1) {			    /* this was the only subdisk */
		Free(plex->sdnos);			    /* free the subdisk array */
		plex->sdnos = NULL;			    /* and note the fact */
		plex->subdisks_allocated = 0;		    /* no subdisk space */
	    } else {
		for (sdno = 0; sdno < plex->subdisks; sdno++) {
		    if (plex->sdnos[sdno] == msg->index)    /* found our subdisk */
			break;
		}
		if (sdno < (plex->subdisks - 1))	    /* not the last one, compact */
		    bcopy(&plex->sdnos[sdno + 1],
			&plex->sdnos[sdno],
			(plex->subdisks - 1 - sdno) * sizeof(int));
	    }
	    plex->subdisks--;
	    if (!bcmp(plex->name, sd->name, strlen(plex->name) + 1))
		/* this subdisk is named after the plex */
	    {
		bcopy(sd->name,
		    &sd->name[3],
		    imin(strlen(sd->name) + 1, MAXSDNAME - 3));
		bcopy("ex-", sd->name, 3);
		sd->name[MAXSDNAME - 1] = '\0';
	    }
	    update_plex_config(plex->plexno, 0);
	    if (isstriped(plex))			    /* we've just mutilated our plex, */
		set_plex_state(plex->plexno,
		    plex_down,
		    setstate_force | setstate_configuring);
	    save_config();
	    reply->error = 0;
	}
	return;

    case plex_object:
	plex = validplex(msg->index, reply);		    /* get plex */
	if (plex == NULL)
	    return;
	if (plex->volno >= 0) {
	    int volno = plex->volno;

	    vol = &VOL[volno];
	    if ((!msg->force)				    /* don't force things */
	    &&((vol->state == volume_up)		    /* and the volume is up */
	    &&(vol->plexes == 1))) {			    /* and this is the last plex */
		/*
		   * XXX As elsewhere, check whether we will lose
		   * mapping by removing this plex
		 */
		reply->error = EBUSY;			    /* we need this plex */
		reply->msg[0] = '\0';
		return;
	    }
	    plex->volno = -1;				    /* anonymous plex */
	    for (plexno = 0; plexno < vol->plexes; plexno++) {
		if (vol->plex[plexno] == msg->index)	    /* found our plex */
		    break;
	    }
	    if (plexno < (vol->plexes - 1))		    /* not the last one, compact */
		bcopy(&vol->plex[plexno + 1],
		    &vol->plex[plexno],
		    (vol->plexes - 1 - plexno) * sizeof(int));
	    vol->plexes--;
	    vol->last_plex_read = 0;			    /* don't go beyond the end */
	    if (!bcmp(vol->name, plex->name, strlen(vol->name) + 1))
		/* this plex is named after the volume */
	    {
		/* First, check if the subdisks are the same */
		if (msg->recurse) {
		    int sdno;

		    for (sdno = 0; sdno < plex->subdisks; sdno++) {
			struct sd *sd = &SD[plex->sdnos[sdno]];

			if (!bcmp(plex->name, sd->name, strlen(plex->name) + 1))
							    /* subdisk is named after the plex */
			{
			    bcopy(sd->name,
				&sd->name[3],
				imin(strlen(sd->name) + 1, MAXSDNAME - 3));
			    bcopy("ex-", sd->name, 3);
			    sd->name[MAXSDNAME - 1] = '\0';
			}
		    }
		}
		bcopy(plex->name,
		    &plex->name[3],
		    imin(strlen(plex->name) + 1, MAXPLEXNAME - 3));
		bcopy("ex-", plex->name, 3);
		plex->name[MAXPLEXNAME - 1] = '\0';
	    }
	    update_volume_config(volno, 0);
	    save_config();
	    reply->error = 0;
	} else {
	    reply->error = ENOENT;
	    strcpy(reply->msg, "Plex is not attached");
	}
    }
}
Пример #23
0
/*!
 ************************************************************************
 * \brief
 *    Initialize reference lists depending on current slice type
 *
 ************************************************************************
 */
void init_lists_mvc(Slice *currSlice)
{
  VideoParameters *p_Vid = currSlice->p_Vid;
  DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;

  unsigned int i;
  int j;

  int list0idx = 0;
  int list0idx_1 = 0;
  int listltidx = 0;

  FrameStore **fs_list0;
  FrameStore **fs_list1;
  FrameStore **fs_listlt;

  int currPOC = currSlice->ThisPOC;
  int curr_view_id = currSlice->view_id;
  int anchor_pic_flag = currSlice->anchor_pic_flag;

  currSlice->listinterviewidx0 = 0;
	currSlice->listinterviewidx1 = 0;

  if ((currSlice->slice_type == I_SLICE)||(currSlice->slice_type == SI_SLICE))
  {
    currSlice->listXsize[0] = 0;
    currSlice->listXsize[1] = 0;
    return;
  }

  if ((currSlice->slice_type == P_SLICE)||(currSlice->slice_type == SP_SLICE))
  {
    if (currSlice->structure == FRAME)
    {
      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used==3)
        {
          if ((p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Dpb->fs_ref[i]->frame->is_long_term) && (p_Dpb->fs_ref[i]->frame->view_id == curr_view_id))
          {
            currSlice->listX[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
          }
        }
      }
      // order list 0 by PicNum
      qsort((void *)currSlice->listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
      currSlice->listXsize[0] = (char) list0idx;
      //printf("listX[0] (PicNum): "); for (i=0; i<list0idx; i++){printf ("%d  ", currSlice->listX[0][i]->pic_num);} printf("\n");

      // long term handling
      for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ltref[i]->is_used==3)
        {
          if (p_Dpb->fs_ltref[i]->frame->is_long_term && (p_Dpb->fs_ltref[i]->frame->view_id == curr_view_id))
          {
            currSlice->listX[0][list0idx++]=p_Dpb->fs_ltref[i]->frame;
          }
        }
      }
      qsort((void *)&currSlice->listX[0][(short) currSlice->listXsize[0]], list0idx - currSlice->listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
      currSlice->listXsize[0] = (char) list0idx;
    }
    else
    {
      fs_list0 = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==fs_list0)
         no_mem_exit("init_lists: fs_list0");
      fs_listlt = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==fs_listlt)
         no_mem_exit("init_lists: fs_listlt");

      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_reference && (p_Dpb->fs_ref[i]->view_id == curr_view_id))
        {
          fs_list0[list0idx++] = p_Dpb->fs_ref[i];
        }
      }

      qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_frame_num_desc);

      //printf("fs_list0 (FrameNum): "); for (i=0; i<list0idx; i++){printf ("%d  ", fs_list0[i]->frame_num_wrap);} printf("\n");

      currSlice->listXsize[0] = 0;
      gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listX[0], &currSlice->listXsize[0], 0);

      //printf("listX[0] (PicNum): "); for (i=0; i < currSlice->listXsize[0]; i++){printf ("%d  ", currSlice->listX[0][i]->pic_num);} printf("\n");

      // long term handling
      for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ltref[i]->view_id == curr_view_id)
        fs_listlt[listltidx++]=p_Dpb->fs_ltref[i];
      }

      qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);

      gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listX[0], &currSlice->listXsize[0], 1);

      free(fs_list0);
      free(fs_listlt);
    }
    currSlice->listXsize[1] = 0;
  }
  else
  {
    // B-Slice
    if (currSlice->structure == FRAME)
    {
      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used==3)
        {
          if ((p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Dpb->fs_ref[i]->frame->is_long_term) && (p_Dpb->fs_ref[i]->frame->view_id == curr_view_id))
          {
            if (currSlice->framepoc >= p_Dpb->fs_ref[i]->frame->poc) //!KS use >= for error concealment
//            if (p_Vid->framepoc > p_Dpb->fs_ref[i]->frame->poc)
            {
              currSlice->listX[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
            }
          }
        }
      }
      qsort((void *)currSlice->listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
      list0idx_1 = list0idx;
      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used==3)
        {
          if ((p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Dpb->fs_ref[i]->frame->is_long_term) && (p_Dpb->fs_ref[i]->frame->view_id == curr_view_id))
          {
            if (currSlice->framepoc < p_Dpb->fs_ref[i]->frame->poc)
            {
              currSlice->listX[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
            }
          }
        }
      }
      qsort((void *)&currSlice->listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);

      for (j=0; j<list0idx_1; j++)
      {
        currSlice->listX[1][list0idx-list0idx_1+j]=currSlice->listX[0][j];
      }
      for (j=list0idx_1; j<list0idx; j++)
      {
        currSlice->listX[1][j-list0idx_1]=currSlice->listX[0][j];
      }

      currSlice->listXsize[0] = currSlice->listXsize[1] = (char) list0idx;

//      printf("currSlice->listX[0] currPoc=%d (Poc): ", p_Vid->framepoc); for (i=0; i<currSlice->listXsize[0]; i++){printf ("%d  ", currSlice->listX[0][i]->poc);} printf("\n");
//      printf("currSlice->listX[1] currPoc=%d (Poc): ", p_Vid->framepoc); for (i=0; i<currSlice->listXsize[1]; i++){printf ("%d  ", currSlice->listX[1][i]->poc);} printf("\n");

      // long term handling
      for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ltref[i]->is_used==3)
        {
          if (p_Dpb->fs_ltref[i]->frame->is_long_term && (p_Dpb->fs_ltref[i]->frame->view_id == curr_view_id))
          {
            currSlice->listX[0][list0idx]   = p_Dpb->fs_ltref[i]->frame;
            currSlice->listX[1][list0idx++] = p_Dpb->fs_ltref[i]->frame;
          }
        }
      }
      qsort((void *)&currSlice->listX[0][(short) currSlice->listXsize[0]], list0idx - currSlice->listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
      qsort((void *)&currSlice->listX[1][(short) currSlice->listXsize[0]], list0idx - currSlice->listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
      currSlice->listXsize[0] = currSlice->listXsize[1] = (char) list0idx;
    }
    else
    {
      fs_list0 = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==fs_list0)
         no_mem_exit("init_lists: fs_list0");
      fs_list1 = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==fs_list1)
         no_mem_exit("init_lists: fs_list1");
      fs_listlt = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==fs_listlt)
         no_mem_exit("init_lists: fs_listlt");

      currSlice->listXsize[0] = 0;
      currSlice->listXsize[1] = 1;

      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used)
        {
          if (currSlice->ThisPOC >= p_Dpb->fs_ref[i]->poc && (p_Dpb->fs_ref[i]->view_id == curr_view_id))
          {
            fs_list0[list0idx++] = p_Dpb->fs_ref[i];
          }
        }
      }
      qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_poc_desc);
      list0idx_1 = list0idx;
      for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ref[i]->is_used)
        {
          if (currSlice->ThisPOC < p_Dpb->fs_ref[i]->poc && (p_Dpb->fs_ref[i]->view_id == curr_view_id))
          {
            fs_list0[list0idx++] = p_Dpb->fs_ref[i];
          }
        }
      }
      qsort((void *)&fs_list0[list0idx_1], list0idx-list0idx_1, sizeof(FrameStore*), compare_fs_by_poc_asc);

      for (j=0; j<list0idx_1; j++)
      {
        fs_list1[list0idx-list0idx_1+j]=fs_list0[j];
      }
      for (j=list0idx_1; j<list0idx; j++)
      {
        fs_list1[j-list0idx_1]=fs_list0[j];
      }

//      printf("fs_list0 currPoc=%d (Poc): ", currSlice->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d  ", fs_list0[i]->poc);} printf("\n");
//      printf("fs_list1 currPoc=%d (Poc): ", currSlice->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d  ", fs_list1[i]->poc);} printf("\n");

      currSlice->listXsize[0] = 0;
      currSlice->listXsize[1] = 0;
      gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listX[0], &currSlice->listXsize[0], 0);
      gen_pic_list_from_frame_list(currSlice->structure, fs_list1, list0idx, currSlice->listX[1], &currSlice->listXsize[1], 0);

//      printf("currSlice->listX[0] currPoc=%d (Poc): ", p_Vid->framepoc); for (i=0; i<currSlice->listXsize[0]; i++){printf ("%d  ", currSlice->listX[0][i]->poc);} printf("\n");
//      printf("currSlice->listX[1] currPoc=%d (Poc): ", p_Vid->framepoc); for (i=0; i<currSlice->listXsize[1]; i++){printf ("%d  ", currSlice->listX[1][i]->poc);} printf("\n");

      // long term handling
      for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
      {
        if (p_Dpb->fs_ltref[i]->view_id == curr_view_id)
        fs_listlt[listltidx++]=p_Dpb->fs_ltref[i];
      }

      qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);

      gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listX[0], &currSlice->listXsize[0], 1);
      gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listX[1], &currSlice->listXsize[1], 1);

      free(fs_list0);
      free(fs_list1);
      free(fs_listlt);
    }
  }

  if ((currSlice->listXsize[0] == currSlice->listXsize[1]) && (currSlice->listXsize[0] > 1))
  {
    // check if lists are identical, if yes swap first two elements of currSlice->listX[1]
    int diff=0;
    for (j = 0; j< currSlice->listXsize[0]; j++)
    {
      if (currSlice->listX[0][j]!=currSlice->listX[1][j])
        diff=1;
    }
    if (!diff)
    {
      StorablePicture *tmp_s = currSlice->listX[1][0];
      currSlice->listX[1][0]=currSlice->listX[1][1];
      currSlice->listX[1][1]=tmp_s;
    }
  }

  if (currSlice->svc_extension_flag==0)
  {
    if ((currSlice->slice_type == P_SLICE)||(currSlice->slice_type == SP_SLICE))
    {
      currSlice->fs_listinterview0 = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==currSlice->fs_listinterview0)
        no_mem_exit("init_lists: fs_listinterview0");
      list0idx = currSlice->listXsize[0];
      if (currSlice->structure == FRAME)
      {	
        append_interview_list(p_Dpb, 0, 0, currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_view_id, anchor_pic_flag);

        for (i=0; i<(unsigned int)currSlice->listinterviewidx0; i++)
        {
          currSlice->listX[0][list0idx++]=currSlice->fs_listinterview0[i]->frame;
        }
        currSlice->listXsize[0] = (char) list0idx;
      }
      else
      {
        append_interview_list(p_Dpb, currSlice->structure, 0, currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_view_id, anchor_pic_flag);
        gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0, currSlice->listinterviewidx0, currSlice->listX[0], &currSlice->listXsize[0]);
      }
    }
    else
    {
      // B-Slice
      currSlice->fs_listinterview0 = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==currSlice->fs_listinterview0)
        no_mem_exit("init_lists: fs_listinterview0");
      currSlice->fs_listinterview1 = calloc(p_Dpb->size, sizeof (FrameStore*));
      if (NULL==currSlice->fs_listinterview1)
        no_mem_exit("init_lists: fs_listinterview1");
      list0idx = currSlice->listXsize[0];
      if (currSlice->structure == FRAME)
      {	
        append_interview_list(p_Dpb, 0, 0, currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_view_id, anchor_pic_flag);
        append_interview_list(p_Dpb, 0, 1, currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_view_id, anchor_pic_flag);

        for (i=0; i<(unsigned int)currSlice->listinterviewidx0; i++)
        {
          currSlice->listX[0][list0idx++]=currSlice->fs_listinterview0[i]->frame;
        }
        currSlice->listXsize[0] = (char) list0idx;
        list0idx = currSlice->listXsize[1];
        for (i=0; i<(unsigned int)currSlice->listinterviewidx1; i++)
        {
          currSlice->listX[1][list0idx++]=currSlice->fs_listinterview1[i]->frame;
        }
        currSlice->listXsize[1] = (char) list0idx;
      }
      else
      {
        append_interview_list(p_Dpb, currSlice->structure, 0, currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_view_id, anchor_pic_flag);
        gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0, currSlice->listinterviewidx0, currSlice->listX[0], &currSlice->listXsize[0]);
        append_interview_list(p_Dpb, currSlice->structure, 1, currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_view_id, anchor_pic_flag);
        gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview1, currSlice->listinterviewidx1, currSlice->listX[1], &currSlice->listXsize[1]);	
      }
    }
  }

  // set max size
  currSlice->listXsize[0] = (char) imin (currSlice->listXsize[0], currSlice->num_ref_idx_active[LIST_0]);
  currSlice->listXsize[1] = (char) imin (currSlice->listXsize[1], currSlice->num_ref_idx_active[LIST_1]);

  // set the unused list entries to NULL
  for (i=currSlice->listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
  {
    currSlice->listX[0][i] = p_Vid->no_reference_picture;
  }
  for (i=currSlice->listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
  {
    currSlice->listX[1][i] = p_Vid->no_reference_picture;
  }
}
Пример #24
0
/*
 * If we have an mbuf chain in cd->mpending, try to parse a record from it,
 * leaving the result in cd->mreq. If we don't have a complete record, leave
 * the partial result in cd->mreq and try to read more from the socket.
 */
static int
svc_vc_process_pending(SVCXPRT *xprt)
{
	struct cf_conn *cd = (struct cf_conn *) xprt->xp_p1;
	struct socket *so = xprt->xp_socket;
	struct mbuf *m;

	/*
	 * If cd->resid is non-zero, we have part of the
	 * record already, otherwise we are expecting a record
	 * marker.
	 */
	if (!cd->resid && cd->mpending) {
		/*
		 * See if there is enough data buffered to
		 * make up a record marker. Make sure we can
		 * handle the case where the record marker is
		 * split across more than one mbuf.
		 */
		size_t n = 0;
		uint32_t header;

		m = cd->mpending;
		while (n < sizeof(uint32_t) && m) {
			n += m->m_len;
			m = m->m_next;
		}
		if (n < sizeof(uint32_t)) {
			so->so_rcv.sb_lowat = sizeof(uint32_t) - n;
			return (FALSE);
		}
		m_copydata(cd->mpending, 0, sizeof(header),
		    (char *)&header);
		header = ntohl(header);
		cd->eor = (header & 0x80000000) != 0;
		cd->resid = header & 0x7fffffff;
		m_adj(cd->mpending, sizeof(uint32_t));
	}

	/*
	 * Start pulling off mbufs from cd->mpending
	 * until we either have a complete record or
	 * we run out of data. We use m_split to pull
	 * data - it will pull as much as possible and
	 * split the last mbuf if necessary.
	 */
	while (cd->mpending && cd->resid) {
		m = cd->mpending;
		if (cd->mpending->m_next
		    || cd->mpending->m_len > cd->resid)
			cd->mpending = m_split(cd->mpending,
			    cd->resid, M_WAITOK);
		else
			cd->mpending = NULL;
		if (cd->mreq)
			m_last(cd->mreq)->m_next = m;
		else
			cd->mreq = m;
		while (m) {
			cd->resid -= m->m_len;
			m = m->m_next;
		}
	}

	/*
	 * Block receive upcalls if we have more data pending,
	 * otherwise report our need.
	 */
	if (cd->mpending)
		so->so_rcv.sb_lowat = INT_MAX;
	else
		so->so_rcv.sb_lowat =
		    imax(1, imin(cd->resid, so->so_rcv.sb_hiwat / 2));
	return (TRUE);
}
Пример #25
0
 /**********************************************************************
 * Handle completion of a command submitted via CAM.
 */
static void
amr_cam_complete(struct amr_command *ac)
{
	struct amr_passthrough		*ap;
	struct amr_ext_passthrough	*aep;
	struct ccb_scsiio		*csio;
	struct scsi_inquiry_data	*inq;
	int				scsi_status, cdb0;

	ap = &ac->ac_ccb->ccb_pthru;
	aep = &ac->ac_ccb->ccb_epthru;
	csio = (struct ccb_scsiio *)ac->ac_private;
	inq = (struct scsi_inquiry_data *)csio->data_ptr;

	if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
		scsi_status = aep->ap_scsi_status;
	else
		scsi_status = ap->ap_scsi_status;
	debug(1, "status 0x%x  AP scsi_status 0x%x", ac->ac_status,
	    scsi_status);

	/* Make sure the status is sane */
	if ((ac->ac_status != AMR_STATUS_SUCCESS) && (scsi_status == 0)) {
		csio->ccb_h.status = CAM_REQ_CMP_ERR;
		goto out;
	}

	/*
	 * Hide disks from CAM so that they're not picked up and treated as
	 * 'normal' disks.
	 *
	 * If the configuration provides a mechanism to mark a disk a "not
	 * managed", we could add handling for that to allow disks to be
	 * selectively visible.
	 */

	/* handle passthrough SCSI status */
	switch(scsi_status) {
	case 0:	/* completed OK */
		if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
			cdb0 = aep->ap_cdb[0];
		else
			cdb0 = ap->ap_cdb[0];
		if ((cdb0 == INQUIRY) && (SID_TYPE(inq) == T_DIRECT))
			inq->device = (inq->device & 0xe0) | T_NODEVICE;
		csio->ccb_h.status = CAM_REQ_CMP;
		break;

	case 0x02:
		csio->ccb_h.status = CAM_SCSI_STATUS_ERROR;
		csio->scsi_status = SCSI_STATUS_CHECK_COND;
		if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
			bcopy(aep->ap_request_sense_area, &csio->sense_data,
			    AMR_MAX_REQ_SENSE_LEN);
		else
			bcopy(ap->ap_request_sense_area, &csio->sense_data,
			    AMR_MAX_REQ_SENSE_LEN);
		csio->sense_len = AMR_MAX_REQ_SENSE_LEN;
		csio->ccb_h.status |= CAM_AUTOSNS_VALID;
		break;

	case 0x08:
		csio->ccb_h.status = CAM_SCSI_BUSY;
		break;

	case 0xf0:
	case 0xf4:
	default:
		/*
		 * Non-zero LUNs are already filtered, so there's no need
		 * to return CAM_DEV_NOT_THERE.
		 */
		csio->ccb_h.status = CAM_SEL_TIMEOUT;
		break;
	}

out:
	if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
		debug(2, "%*D\n", imin(csio->dxfer_len, 16), csio->data_ptr,
		    " ");

	mtx_lock(&ac->ac_sc->amr_list_lock);
	xpt_done((union ccb *)csio);
	amr_releasecmd(ac);
	mtx_unlock(&ac->ac_sc->amr_list_lock);
}
Пример #26
0
/*
 * I/O ops
 */
static	int
ptcwrite(struct dev_write_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct tty *tp = dev->si_tty;
	u_char *cp = NULL;
	int cc = 0;
	u_char locbuf[BUFSIZ];
	int cnt = 0;
	struct pt_ioctl *pti = dev->si_drv1;
	int error = 0;

	lwkt_gettoken(&tty_token);
again:
	if ((tp->t_state&TS_ISOPEN) == 0)
		goto block;
	if (pti->pt_flags & PF_REMOTE) {
		if (tp->t_canq.c_cc)
			goto block;
		while ((ap->a_uio->uio_resid > 0 || cc > 0) &&
		       tp->t_canq.c_cc < TTYHOG - 1) {
			if (cc == 0) {
				cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
				cc = imin(cc, TTYHOG - 1 - tp->t_canq.c_cc);
				cp = locbuf;
				error = uiomove(cp, (size_t)cc, ap->a_uio);
				if (error) {
					lwkt_reltoken(&tty_token);
					return (error);
				}
				/* check again for safety */
				if ((tp->t_state & TS_ISOPEN) == 0) {
					/* adjust as usual */
					ap->a_uio->uio_resid += cc;
					lwkt_reltoken(&tty_token);
					return (EIO);
				}
			}
			if (cc > 0) {
				cc = b_to_q((char *)cp, cc, &tp->t_canq);
				/*
				 * XXX we don't guarantee that the canq size
				 * is >= TTYHOG, so the above b_to_q() may
				 * leave some bytes uncopied.  However, space
				 * is guaranteed for the null terminator if
				 * we don't fail here since (TTYHOG - 1) is
				 * not a multiple of CBSIZE.
				 */
				if (cc > 0)
					break;
			}
		}
		/* adjust for data copied in but not written */
		ap->a_uio->uio_resid += cc;
		clist_putc(0, &tp->t_canq);
		ttwakeup(tp);
		wakeup(TSA_PTS_READ(tp));
		lwkt_reltoken(&tty_token);
		return (0);
	}
	while (ap->a_uio->uio_resid > 0 || cc > 0) {
		if (cc == 0) {
			cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
			cp = locbuf;
			error = uiomove(cp, (size_t)cc, ap->a_uio);
			if (error) {
				lwkt_reltoken(&tty_token);
				return (error);
			}
			/* check again for safety */
			if ((tp->t_state & TS_ISOPEN) == 0) {
				/* adjust for data copied in but not written */
				ap->a_uio->uio_resid += cc;
				lwkt_reltoken(&tty_token);
				return (EIO);
			}
		}
		while (cc > 0) {
			if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
			   (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
				wakeup(TSA_HUP_OR_INPUT(tp));
				goto block;
			}
			(*linesw[tp->t_line].l_rint)(*cp++, tp);
			cnt++;
			cc--;
		}
		cc = 0;
	}
	lwkt_reltoken(&tty_token);
	return (0);
block:
	/*
	 * Come here to wait for slave to open, for space
	 * in outq, or space in rawq, or an empty canq.
	 */
	if ((tp->t_state & TS_CONNECTED) == 0) {
		/* adjust for data copied in but not written */
		ap->a_uio->uio_resid += cc;
		lwkt_reltoken(&tty_token);
		return (EIO);
	}
	if (ap->a_ioflag & IO_NDELAY) {
		/* adjust for data copied in but not written */
		ap->a_uio->uio_resid += cc;
		if (cnt == 0) {
			lwkt_reltoken(&tty_token);
			return (EWOULDBLOCK);
		}
		lwkt_reltoken(&tty_token);
		return (0);
	}
	error = tsleep(TSA_PTC_WRITE(tp), PCATCH, "ptcout", 0);
	if (error) {
		/* adjust for data copied in but not written */
		ap->a_uio->uio_resid += cc;
		lwkt_reltoken(&tty_token);
		return (error);
	}
	goto again;
}
Пример #27
0
int PMR_process_s_task(singleton_t *sng, int tid, proc_t *procinfo,
		       val_t *Wstruct, vec_t *Zstruct, 
		       tol_t *tolstruct, counter_t *num_left, 
		       double *work, int *iwork)
{
  /* Inputs */
  int    begin         = sng->begin; 
  int    end           = sng->end;
  int    bl_begin      = sng->bl_begin;
  int    bl_end        = sng->bl_end;
  int    bl_size       = bl_end - bl_begin + 1;
  double bl_spdiam     = sng->bl_spdiam; 
  rrr_t  *RRR          = sng->RRR;
  double *restrict D   = RRR->D; 
  double *restrict L   = RRR->L; 
  double *restrict DL  = RRR->DL;
  double *restrict DLL = RRR->DLL;

  int              pid      = procinfo->pid;  
  int              n        = Wstruct->n;
  double *restrict W        = Wstruct->W;
  double *restrict Werr     = Wstruct->Werr;
  double *restrict Wgap     = Wstruct->Wgap;
  int    *restrict Windex   = Wstruct->Windex;  
  int    *restrict iproc    = Wstruct->iproc;  
  double *restrict Wshifted = Wstruct->Wshifted;
  int              ldz      = Zstruct->ldz;
  double *restrict Z        = Zstruct->Z;
  int    *restrict isuppZ   = Zstruct->Zsupp;;
  int    *restrict Zindex   = Zstruct->Zindex;
  double           pivmin   = tolstruct->pivmin;

  /* others */
  int              info, i, k, itmp, num_decrement=0;
  int              IONE = 1;
  double           DZERO = 0.0;
  double           tol, lambda, left, right;
  int              i_local, zind;
  double           gap, lgap, rgap, gaptol, savedgap, tmp;
  int             usedBS, usedRQ, needBS, wantNC, step2II;
  int              r, offset;
  double           twoeps = 2*DBL_EPSILON, RQtol = 2*DBL_EPSILON;
  double           residual, bstres, bstw; 
  int              i_supmn, i_supmx;
  double           RQcorr;
  int              negcount;
  int              sgndef, suppsize;
  double           sigma;
  int              i_Zfrom, i_Zto;
  double           ztz, norminv, mingma;


  /* set tolerance parameter */
  tol  = 4.0 * log( (double) bl_size ) * DBL_EPSILON;

  /* loop over all singletons in the task */
  for (i=begin; i<=end; i++) {

    /* check if eigenvector is supposed to be computed by
     * the process */
    if (iproc[i] != pid)
      continue;
    num_decrement++;

    if (bl_size == 1) {
      /* set eigenvector to column of identity matrix */
      zind = Zindex[i];
      memset(&Z[zind*ldz], 0.0, n*sizeof(double) );
      Z[zind*ldz + bl_begin] = 1.0;
      isuppZ[2*zind    ]     = bl_begin + 1;
      isuppZ[2*zind + 1]     = bl_begin + 1;
      continue;
    }

    lambda  = Wshifted[i];  
    left    = Wshifted[i] - Werr[i];
    right   = Wshifted[i] + Werr[i];
    i_local = Windex[i];
    r       = 0;
    
    /* compute left and right gap */
    if (i == bl_begin)
      lgap = DBL_EPSILON * fmax( fabs(left), fabs(right) );
    else if (i == begin)
      lgap = sng->lgap;
    else
      lgap = Wgap[i-1];

    if (i == bl_end) {
      rgap = DBL_EPSILON * fmax( fabs(left), fabs(right) );
    } else {
      rgap = Wgap[i];
    }

    gap = fmin(lgap, rgap);

    if ( i == bl_begin || i == bl_end ) {
      gaptol = 0.0;
    } else {
      gaptol = gap * DBL_EPSILON;
    }

    /* initialize lower and upper value of support */
    i_supmn = bl_size;
    i_supmx = 1;

    /* update Wgap so that it holds minimum gap and save the 
     * old value */
    savedgap  = Wgap[i];
    Wgap[i]   = gap;
    
    /* initialize flags indicating if bisection or Rayleigh-Quotient
     * correction was used */
    usedBS = false;
    usedRQ = false;
  
    /* the need for bisection is initially turned off */
    needBS = !TRY_RQC;

    /* IEEE floating point is assumed, so that all 0 bits are 0.0 */
    zind = Zindex[i];
    memset(&Z[zind*ldz], 0.0, n*sizeof(double));

    /* inverse iteration with twisted factorization */
    for (k=1; k<=MAXITER; k++) {

      if (needBS == true) {
	usedBS = true;
	itmp   = r;
	
	offset  = Windex[i] - 1;
	tmp     = Wgap[i]; 
	Wgap[i] = 0.0;
	
	odrrb_(&bl_size, D, DLL, &i_local, &i_local, &DZERO, 
		&twoeps, &offset, &Wshifted[i], &Wgap[i],
		&Werr[i], work, iwork, &pivmin, &bl_spdiam,
		&itmp, &info);
	assert(info == 0);
	
	Wgap[i] = tmp;
	lambda = Wshifted[i];
	r = 0;
      }
      wantNC = (usedBS == true) ? false : true;

      /* compute the eigenvector corresponding to lambda */
      odr1v_(&bl_size, &IONE, &bl_size, &lambda, D, L, DL, DLL,
	      &pivmin, &gaptol, &Z[zind*ldz+bl_begin], &wantNC,
	      &negcount, &ztz, &mingma, &r, &isuppZ[2*zind],
	      &norminv, &residual, &RQcorr, work);

      if (k == 1) {
	bstres = residual;
	bstw   = lambda;
      } else if (residual < bstres) {
	bstres = residual;
	bstw   = lambda;
      }
      
      /* update support held */
      i_supmn = imin(i_supmn, isuppZ[2*zind    ]);
      i_supmx = imax(i_supmx, isuppZ[2*zind + 1]);

      /* Convergence test for Rayleigh Quotient Iteration
       * not done if bisection was used */
      if ( !usedBS && residual > tol*gap 
	   && fabs(RQcorr) > RQtol*fabs(lambda) ) {
      
	if (i_local <= negcount) {
	  sgndef = -1;    /* wanted eigenvalue lies to the left  */
	} else {
	  sgndef =  1;    /* wanted eigenvalue lies to the right */
	}
	
	if ( RQcorr*sgndef >= 0.0
	     && lambda+RQcorr <= right 
	     && lambda+RQcorr >= left ) {
	  usedRQ = true;
	  if ( sgndef == 1 )
	    left  = lambda;
	  else
	    right = lambda;
	  Wshifted[i] = 0.5*(left + right);
	  lambda     += RQcorr;
	} else { /* bisection is needed */
	  needBS = true;
	}
	
	if ( right-left < RQtol*fabs(lambda) ) {
	  /* eigenvalue computed to bisection accuracy
	   * => compute eigenvector */
	  usedBS = true;
	} else if ( k == MAXITER-1 ) {
	  /* for last iteration use bisection */
	  needBS = true;
	}
      } else {
	/* go to next iteration */
	break;
      }

    } /* end k */

    /* if necessary call odr1v to improve error angle by 2nd step */
    step2II = false;
    if ( usedRQ && usedBS && (bstres <= residual) ) {
      lambda = bstw;
      step2II = true;
    }
    if ( step2II == true ) {
      odr1v_(&bl_size, &IONE, &bl_size, &lambda, D, L, DL, DLL,
	      &pivmin, &gaptol, &Z[zind*ldz+bl_begin], &wantNC,
	      &negcount, &ztz, &mingma, &r, &isuppZ[2*zind],
	      &norminv, &residual, &RQcorr, work);
    }
    Wshifted[i] = lambda;

    /* compute support w.r.t. whole matrix
     * block beginning is offset for each support */
    isuppZ[2*zind    ] += bl_begin;
    isuppZ[2*zind + 1] += bl_begin;
  
    /* ensure vector is okay if support changed in RQI 
     * minus ones because of indices starting from zero */
    i_Zfrom    = isuppZ[2*zind    ] - 1;
    i_Zto      = isuppZ[2*zind + 1] - 1;
    i_supmn   += bl_begin - 1;
    i_supmx   += bl_begin - 1;
    if ( i_supmn < i_Zfrom ) {
      for ( k=i_supmn; k < i_Zfrom; k++ ) {
	Z[k + zind*ldz] = 0.0;
      }
    }
    if ( i_supmx > i_Zto ) {
      for ( k=i_Zto+1; k <= i_supmx; k++ ) {
	Z[k + zind*ldz] = 0.0;
      }
    }
    
    /* normalize eigenvector */
    suppsize = i_Zto - i_Zfrom + 1;
    odscl_(&suppsize, &norminv, &Z[i_Zfrom + zind*ldz], &IONE);

    sigma = L[bl_size-1];
    W[i]  = lambda + sigma;
    
    if (i < end)
      Wgap[i] = fmax(savedgap, W[i+1]-Werr[i+1] - W[i]-Werr[i]);

  } /* end i */

  /* decrement counter */
  PMR_decrement_counter(num_left, num_decrement);

  /* clean up */
  free(sng);
  PMR_try_destroy_rrr(RRR);

  return(0);
}
Пример #28
0
/* reset and initialize the device */
static int
atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	atkbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	int delay[2];
	int *data = (int *)arg;	/* data[0]: controller, data[1]: irq */

	/* XXX */
	if (unit == ATKBD_DEFAULT) {
		*kbdp = kbd = &default_kbd;
		if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
			return 0;
		state = &default_kbd_state;
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size =
			sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
	} else if (*kbdp == NULL) {
		*kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT | M_ZERO);
		state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT | M_ZERO);
		keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
		accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
		fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
		fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
		if ((kbd == NULL) || (state == NULL) || (keymap == NULL)
		     || (accmap == NULL) || (fkeymap == NULL)) {
			if (state != NULL)
				free(state, M_DEVBUF);
			if (keymap != NULL)
				free(keymap, M_DEVBUF);
			if (accmap != NULL)
				free(accmap, M_DEVBUF);
			if (fkeymap != NULL)
				free(fkeymap, M_DEVBUF);
			if (kbd != NULL)
				free(kbd, M_DEVBUF);
			return ENOMEM;
		}
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (atkbd_state_t *)kbd->kb_data;
		bzero(state, sizeof(*state));
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
	}

	if (!KBD_IS_PROBED(kbd)) {
		state->kbdc = atkbdc_open(data[0]);
		if (state->kbdc == NULL)
			return ENXIO;
		kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
				0, 0);
		bcopy(&key_map, keymap, sizeof(key_map));
		bcopy(&accent_map, accmap, sizeof(accent_map));
		bcopy(fkey_tab, fkeymap,
		      imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
		kbd->kb_data = (void *)state;
	
		if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */
			if (flags & KB_CONF_FAIL_IF_NO_KBD)
				return ENXIO;
		} else {
			KBD_FOUND_DEVICE(kbd);
		}
		atkbd_clear_state(kbd);
		state->ks_mode = K_XLATE;
		/* 
		 * FIXME: set the initial value for lock keys in ks_state
		 * according to the BIOS data?
		 */
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
		if (KBD_HAS_DEVICE(kbd)
	    	    && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
	    	    && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
			return ENXIO;
		atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
		get_typematic(kbd);
		delay[0] = kbd->kb_delay1;
		delay[1] = kbd->kb_delay2;
		atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0)
			return ENXIO;
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}
Пример #29
0
/*!
 ************************************************************************
 * \brief
 *    Generate box-out slice group map type MapUnit map (type 3)
 *
 ************************************************************************
 */
static void FmoGenerateType3MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
{
  unsigned i, k;
  int leftBound, topBound, rightBound, bottomBound;
  int x, y, xDir, yDir;
  int mapUnitVacant;

  unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);

  for( i = 0; i < PicSizeInMapUnits; i++ )
    MapUnitToSliceGroupMap[ i ] = 2;

  x = ( img->PicWidthInMbs - pps->slice_group_change_direction_flag ) / 2;
  y = ( img->PicHeightInMapUnits - pps->slice_group_change_direction_flag ) / 2;

  leftBound   = x;
  topBound    = y;
  rightBound  = x;
  bottomBound = y;

  xDir =  pps->slice_group_change_direction_flag - 1;
  yDir =  pps->slice_group_change_direction_flag;

  for( k = 0; k < PicSizeInMapUnits; k += mapUnitVacant )
  {
    mapUnitVacant = ( MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ]  ==  2 );
    if( mapUnitVacant )
       MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = ( k >= mapUnitsInSliceGroup0 );

    if( xDir  ==  -1  &&  x  ==  leftBound )
    {
      leftBound = imax( leftBound - 1, 0 );
      x = leftBound;
      xDir = 0;
      yDir = 2 * pps->slice_group_change_direction_flag - 1;
    }
    else
      if( xDir  ==  1  &&  x  ==  rightBound )
      {
        rightBound = imin( rightBound + 1, (int)img->PicWidthInMbs - 1 );
        x = rightBound;
        xDir = 0;
        yDir = 1 - 2 * pps->slice_group_change_direction_flag;
      }
      else
        if( yDir  ==  -1  &&  y  ==  topBound )
        {
          topBound = imax( topBound - 1, 0 );
          y = topBound;
          xDir = 1 - 2 * pps->slice_group_change_direction_flag;
          yDir = 0;
         }
        else
          if( yDir  ==  1  &&  y  ==  bottomBound )
          {
            bottomBound = imin( bottomBound + 1, (int)img->PicHeightInMapUnits - 1 );
            y = bottomBound;
            xDir = 2 * pps->slice_group_change_direction_flag - 1;
            yDir = 0;
          }
          else
          {
            x = x + xDir;
            y = y + yDir;
          }
  }

}
Пример #30
0
static int
mlxd_attach(device_t dev)
{
    struct mlxd_softc	*sc = (struct mlxd_softc *)device_get_softc(dev);
    device_t		parent;
    char		*state;
    int			s1, s2;
    
    debug_called(1);

    parent = device_get_parent(dev);
    sc->mlxd_controller = (struct mlx_softc *)device_get_softc(parent);
    sc->mlxd_unit = device_get_unit(dev);
    sc->mlxd_drive = device_get_ivars(dev);
    sc->mlxd_dev = dev;

    switch(sc->mlxd_drive->ms_state) {
    case MLX_SYSD_ONLINE:
	state = "online";
	break;
    case MLX_SYSD_CRITICAL:
	state = "critical";
	break;
    case MLX_SYSD_OFFLINE:
	state = "offline";
	break;
    default:
	state = "unknown state";
    }

    device_printf(dev, "%uMB (%u sectors) RAID %d (%s)\n",
		  sc->mlxd_drive->ms_size / ((1024 * 1024) / MLX_BLKSIZE),
		  sc->mlxd_drive->ms_size, sc->mlxd_drive->ms_raidlevel, state);

    sc->mlxd_disk = disk_alloc();
    sc->mlxd_disk->d_open = mlxd_open;
    sc->mlxd_disk->d_close = mlxd_close;
    sc->mlxd_disk->d_ioctl = mlxd_ioctl;
    sc->mlxd_disk->d_strategy = mlxd_strategy;
    sc->mlxd_disk->d_name = "mlxd";
    sc->mlxd_disk->d_unit = sc->mlxd_unit;
    sc->mlxd_disk->d_drv1 = sc;
    sc->mlxd_disk->d_sectorsize = MLX_BLKSIZE;
    sc->mlxd_disk->d_mediasize = MLX_BLKSIZE * (off_t)sc->mlxd_drive->ms_size;
    sc->mlxd_disk->d_fwsectors = sc->mlxd_drive->ms_sectors;
    sc->mlxd_disk->d_fwheads = sc->mlxd_drive->ms_heads;
    sc->mlxd_disk->d_flags = DISKFLAG_NEEDSGIANT;

    /* 
     * Set maximum I/O size to the lesser of the recommended maximum and the practical
     * maximum except on v2 cards where the maximum is set to 8 pages.
     */
    if (sc->mlxd_controller->mlx_iftype == MLX_IFTYPE_2)
	sc->mlxd_disk->d_maxsize = 8 * MLX_PAGE_SIZE;
    else {
	s1 = sc->mlxd_controller->mlx_enq2->me_maxblk * MLX_BLKSIZE;
	s2 = (sc->mlxd_controller->mlx_enq2->me_max_sg - 1) * MLX_PAGE_SIZE;
	sc->mlxd_disk->d_maxsize = imin(s1, s2);
    }

    disk_create(sc->mlxd_disk, DISK_VERSION);

    return (0);
}