⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 countbit.c

📁 基于H.263的图像压缩编解码的C源码
💻 C
📖 第 1 页 / 共 3 页
字号:
}

/**********************************************************************
 *
 *      Name:           Count_sac_BitsCoeff
 *                      counts bits using SAC models
 *
 *      Input:          qcoeff, coding mode CBP, bits structure, no. of
 *                      coeffs
 *
 *      Returns:        struct with no. of bits used
 *      Side effects:
 *
 ***********************************************************************/
 
void Count_sac_BitsCoeff(int *qcoeff,int Mode,int CBP,Bits *bits,int ncoeffs)
{
 
  int i;
 
  arith_used = 1;
 
  if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) {
    for (i = 0; i < 4; i++) {
      bits->Y += Code_sac_Coeff(Mode, qcoeff,i,ncoeffs);
    }
    for (i = 4; i < 6; i++) {
      bits->C += Code_sac_Coeff(Mode, qcoeff,i,ncoeffs);
    }
  }
  else {
    for (i = 0; i < 4; i++) {
      if ((i==0 && CBP&32) ||
          (i==1 && CBP&16) ||
          (i==2 && CBP&8) ||
          (i==3 && CBP&4) ||
          (i==4 && CBP&2) ||
          (i==5 && CBP&1)) {
        bits->Y += Code_sac_Coeff(Mode, qcoeff, i, ncoeffs);
      }
    }
    for (i = 4; i < 6; i++) {
      if ((i==0 && CBP&32) ||
          (i==1 && CBP&16) ||
          (i==2 && CBP&8) ||
          (i==3 && CBP&4) ||
          (i==4 && CBP&2) ||
          (i==5 && CBP&1)) {
        bits->C += Code_sac_Coeff(Mode, qcoeff, i, ncoeffs);
      }
    }
  }
  return;
}
 
int Code_sac_Coeff(int Mode, int *qcoeff, int block, int ncoeffs)
{
  int j, bits, mod_index, intra;
  int prev_run, run, prev_level, level, first, prev_position, position;
  int prev_ind, ind, prev_s, s, length;
 
  run = bits = 0;
  first = 1; position = 0; intra = 0;
 
  level = s = ind = 0;
  prev_run = prev_level = prev_ind = prev_s = prev_position = 0;
 
  intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
 
  for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++) {
 
    if (!(j%ncoeffs) && intra) {
      if (trace) {
        fprintf(tf,"DC: ");
      }
      if (qcoeff[block*ncoeffs]!=128)
        mod_index = indexfn(qcoeff[block*ncoeffs],intradctab,254);
      else
        mod_index = indexfn(255,intradctab,254);
      bits += AR_Encode(mod_index, cumf_INTRADC);
    }
    else {
 
      s = 0;
      /* Increment run if coeff is zero */
      if ((level = qcoeff[j]) == 0) {
        run++;
      }
      else {
        /* code run & level and count bits */
        if (level < 0) {
          s = 1;
          level = -level;
        }
        ind = level | run<<4;
        ind = ind | 0<<12; /* Not last coeff */
        position++;
 
        if (!first) {
          mod_index = indexfn(prev_ind, tcoeftab, 103);
          if (prev_level < 13 && prev_run < 64)
            length = CodeTCoef(mod_index, prev_position, intra);
          else
            length = -1;
 
          if (length == -1) {  /* Escape coding */
            if (trace) {
              fprintf(tf,"Escape coding:\n");
            }
 
            if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
 
            mod_index = indexfn(ESCAPE, tcoeftab, 103);
            bits += CodeTCoef(mod_index, prev_position, intra);
 
            if (intra)
              bits += AR_Encode(indexfn(0, lasttab, 2), cumf_LAST_intra);
            else
              bits += AR_Encode(indexfn(0, lasttab, 2), cumf_LAST);
 
            if (intra)
              bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN_intra);
            else
              bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN);
 
            if (intra)
              bits += AR_Encode(indexfn(prev_level, leveltab, 254), 
        cumf_LEVEL_intra);
            else
              bits += AR_Encode(indexfn(prev_level, leveltab, 254), 
        cumf_LEVEL);
 
          }
          else {
            bits += AR_Encode(indexfn(prev_s, signtab, 2), cumf_SIGN);
            bits += length;
          }
        }
 
        prev_run = run; prev_s = s;
        prev_level = level; prev_ind = ind;
        prev_position = position;
 
        run = first = 0;
 
      }
    }
  }
 
  /* Encode Last Coefficient */
 
  if (!first) {
    if (trace) {
      fprintf(tf,"Last coeff: ");
    }
    prev_ind = prev_ind | 1<<12;   /* last coeff */
    mod_index = indexfn(prev_ind, tcoeftab, 103);
 
    if (prev_level  < 13 && prev_run < 64)
      length = CodeTCoef(mod_index, prev_position, intra);
    else
      length = -1;
 
    if (length == -1) {  /* Escape coding */
      if (trace) {
        fprintf(tf,"Escape coding:\n");
      }

      if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
 
      mod_index = indexfn(ESCAPE, tcoeftab, 103);
      bits += CodeTCoef(mod_index, prev_position, intra);
 
      if (intra)
        bits += AR_Encode(indexfn(1, lasttab, 2), cumf_LAST_intra);
      else
        bits += AR_Encode(indexfn(1, lasttab, 2), cumf_LAST);
 
      if (intra)
        bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN_intra);
      else
        bits += AR_Encode(indexfn(prev_run, runtab, 64), cumf_RUN);
 
      if (intra)
        bits += AR_Encode(indexfn(prev_level, leveltab, 254), cumf_LEVEL_intra);
      else
        bits += AR_Encode(indexfn(prev_level, leveltab, 254), cumf_LEVEL);
    }
    else {
      bits += AR_Encode(indexfn(prev_s, signtab, 2), cumf_SIGN);
      bits += length;
    }
  } /* last coeff */
 
  return bits;
}
 
/*********************************************************************
 *
 *      Name:           CodeTCoef
 *
 *      Description:    Encodes an AC Coefficient using the
 *                      relevant SAC model.
 *
 *      Input:          Model index, position in DCT block and intra/
 *                      inter flag.
 *
 *      Returns:        Number of bits used.
 *
 *      Side Effects:   None
 *
 *********************************************************************/

int CodeTCoef(int mod_index, int position, int intra)
{
  int length;
 
  switch (position) {
    case 1:
    {
        if (intra)
          length = AR_Encode(mod_index, cumf_TCOEF1_intra);
        else
          length = AR_Encode(mod_index, cumf_TCOEF1);
        break;
    }
    case 2:
    {
        if (intra)
          length = AR_Encode(mod_index, cumf_TCOEF2_intra);
        else
          length = AR_Encode(mod_index, cumf_TCOEF2);
        break;
    }
    case 3:
    {
        if (intra)
          length = AR_Encode(mod_index, cumf_TCOEF3_intra);
        else
          length = AR_Encode(mod_index, cumf_TCOEF3);
        break;
    }
    default:
    {
        if (intra)
          length = AR_Encode(mod_index, cumf_TCOEFr_intra);
        else
          length = AR_Encode(mod_index, cumf_TCOEFr);
        break;
    }
  }
 
  return length;
}

/**********************************************************************
 *
 *      Name:           FindCBP
 *	Description:	Finds the CBP for a macroblock
 *	
 *      Input:          qcoeff and mode
 *        
 *	Returns:	CBP
 *	Side effects:	
 *
 *      Date: 940829
 *
 ***********************************************************************/


int FindCBP(int *qcoeff, int Mode, int ncoeffs)
{
  
  int i,j;
  int CBP = 0;
  int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);

  /* Set CBP for this Macroblock */
  for (i = 0; i < 6; i++) {
    for (j = i*ncoeffs + intra; j < (i+1)*ncoeffs; j++) {
      if (qcoeff[j]) {
        if (i == 0) {CBP |= 32;}
        else if (i == 1) {CBP |= 16;}
        else if (i == 2) {CBP |= 8;}
        else if (i == 3) {CBP |= 4;}
        else if (i == 4) {CBP |= 2;}
        else if (i == 5) {CBP |= 1;}
        else {
          fprintf(stderr,"Error in CBP assignment\n");
          exit(-1);
        }
        break;
      }
    }
  }

  return CBP;
}

void CountBitsVectors(MotionVector *MV[6][MBR+1][MBC+2], Bits *bits, 
              int x, int y, int Mode, int newgob, Pict *pic)
{
  int y_vec, x_vec;
  int pmv0, pmv1;
  int start,stop,block;

  x++;y++;

  if (Mode == MODE_INTER4V) {
    start = 1; stop = 4;
  }
  else {
    start = 0; stop = 0;
  }

  for (block = start; block <= stop;  block++) {

    FindPMV(MV,x,y,&pmv0,&pmv1, block, newgob, 1);

    x_vec = (2*MV[block][y][x]->x + MV[block][y][x]->x_half) - pmv0;
    y_vec = (2*MV[block][y][x]->y + MV[block][y][x]->y_half) - pmv1;

    if (!long_vectors) {
      if (x_vec < -32) x_vec += 64;
      else if (x_vec > 31) x_vec -= 64;

      if (y_vec < -32) y_vec += 64;
      else if (y_vec > 31) y_vec -= 64;
    }
    else {
      if (pmv0 < -31 && x_vec < -63) x_vec += 64;
      else if (pmv0 > 32 && x_vec > 63) x_vec -= 64;

      if (pmv1 < -31 && y_vec < -63) y_vec += 64;
      else if (pmv1 > 32 && y_vec > 63) y_vec -= 64;
    }
    
    if (trace) {
      fprintf(tf,"Vectors:\n");
    }

    if (x_vec < 0) x_vec += 64;
    if (y_vec < 0) y_vec += 64;

    bits->vec += put_mv (x_vec);
    bits->vec += put_mv (y_vec);

    if (trace) {
      if (x_vec > 31) x_vec -= 64;
      if (y_vec > 31) y_vec -= 64;
      fprintf(tf,"(x,y) = (%d,%d) - ",
              (2*MV[block][y][x]->x + MV[block][y][x]->x_half),
              (2*MV[block][y][x]->y + MV[block][y][x]->y_half));
      fprintf(tf,"(Px,Py) = (%d,%d)\n", pmv0,pmv1);
      fprintf(tf,"(x_diff,y_diff) = (%d,%d)\n",x_vec,y_vec);
    }
  }

  /* PB-frames delta vectors */
  if (pic->PB)
    if (pic->MODB == PBMODE_MVDB || pic->MODB == PBMODE_CBPB_MVDB) {

      x_vec = MV[5][y][x]->x;
      y_vec = MV[5][y][x]->y;

      /* x_vec and y_vec are the PB-delta vectors */
    
      if (x_vec < 0) x_vec += 64;
      if (y_vec < 0) y_vec += 64;

      if (trace) {
        fprintf(tf,"PB delta vectors:\n");
      }

      bits->vec += put_mv (x_vec);
      bits->vec += put_mv (y_vec);

      if (trace) {
        if (x_vec > 31) x_vec -= 64;
        if (y_vec > 31) y_vec -= 64;
        fprintf(tf,"MVDB (x,y) = (%d,%d)\n",x_vec,y_vec);
      }
    }


  return;
}

void Count_sac_BitsVectors(MotionVector *MV[6][MBR+1][MBC+2], Bits *bits,
                      int x, int y, int Mode, int newgob, Pict *pic)
{
  int y_vec, x_vec;
  int pmv0, pmv1;
  int start,stop,block;
 
  arith_used = 1;
  x++;y++;
 
  if (Mode == MODE_INTER4V) {
    start = 1; stop = 4;
  }
  else {
    start = 0; stop = 0;
  }
 
  for (block = start; block <= stop;  block++) {
 
    FindPMV(MV,x,y,&pmv0,&pmv1, block, newgob, 1);
 
    x_vec = (2*MV[block][y][x]->x + MV[block][y][x]->x_half) - pmv0;
    y_vec = (2*MV[block][y][x]->y + MV[block][y][x]->y_half) - pmv1;
 
    if (!long_vectors) {
      if (x_vec < -32) x_vec += 64;
      else if (x_vec > 31) x_vec -= 64;

      if (y_vec < -32) y_vec += 64;
      else if (y_vec > 31) y_vec -= 64;
    }
    else {
      if (pmv0 < -31 && x_vec < -63) x_vec += 64;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -