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

📄 coder.c

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

void ReconImage (int i, int j, MB_Structure *data, PictImage *recon)
{
  int n;
  register int m;

  int x_curr, y_curr;

  x_curr = i * MB_SIZE;
  y_curr = j * MB_SIZE;

  /* Fill in luminance data */
  for (n = 0; n < MB_SIZE; n++)
    for (m= 0; m < MB_SIZE; m++) {
      *(recon->lum + x_curr+m + (y_curr+n)*pels) = data->lum[n][m];
    }

  /* Fill in chrominance data */
  for (n = 0; n < MB_SIZE>>1; n++)
    for (m = 0; m < MB_SIZE>>1; m++) {
      *(recon->Cr + (x_curr>>1)+m + ((y_curr>>1)+n)*cpels) = data->Cr[n][m];
      *(recon->Cb + (x_curr>>1)+m + ((y_curr>>1)+n)*cpels) = data->Cb[n][m];
    }
  return;
}


/**********************************************************************
 *
 *      Name:           InterpolateImage
 *	Description:    Interpolates a complete image for easier half
 *                      pel prediction
 *	
 *	Input:	        pointer to image structure
 *	Returns:        pointer to interpolated image
 *	Side effects:   allocates memory to interpolated image
 *
 ***********************************************************************/


unsigned char *InterpolateImage(unsigned char *image, int width, int height)
{
  unsigned char *ipol_image, *ii, *oo;
  int i,j;

  ipol_image = (unsigned char *)malloc(sizeof(char)*width*height*4);
  ii = ipol_image;
  oo = image;

  /* main image */
  for (j = 0; j < height-1; j++) {
    for (i = 0; i  < width-1; i++) {
      *(ii + (i<<1)) = *(oo + i);
      *(ii + (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
      *(ii + (i<<1)+(width<<1)) = (*(oo + i) + *(oo + i + width) + 1)>>1;
      *(ii + (i<<1)+1+(width<<1)) = (*(oo+i) + *(oo+i+1) + 
         *(oo+i+width) + *(oo+i+1+width) + 2)>>2;
    }
    /* last pels on each line */
    *(ii+ (width<<1) - 2) = *(oo + width - 1);
    *(ii+ (width<<1) - 1) = *(oo + width - 1);
    *(ii+ (width<<1)+ (width<<1)-2) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
    *(ii+ (width<<1)+ (width<<1)-1) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
    ii += (width<<2);
    oo += width;
  }

  /* last lines */
  for (i = 0; i < width-1; i++) {
    *(ii+ (i<<1)) = *(oo + i);    
    *(ii+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
    *(ii+ (width<<1)+ (i<<1)) = *(oo + i);    
    *(ii+ (width<<1)+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
          
  }

  /* bottom right corner pels */
  *(ii + (width<<1) - 2) = *(oo + width -1);
  *(ii + (width<<1) - 1) = *(oo + width -1);
  *(ii + (width<<2) - 2) = *(oo + width -1);
  *(ii + (width<<2) - 1) = *(oo + width -1);

  return ipol_image;
}

/**********************************************************************
 *
 *      Name:           MotionEstimatePicture
 *	Description:    Finds integer and half pel motion estimation
 *                      and chooses 8x8 or 16x16 
 *	
 *	Input:	       current image, previous image, interpolated
 *                     reconstructed previous image, seek_dist,
 *                     motion vector array
 *	Returns:       
 *      Side effects:  allocates memory for MV structure
 *
 ***********************************************************************/


void MotionEstimatePicture(unsigned char *curr, unsigned char *prev, 
           unsigned char *prev_ipol, int seek_dist, 
           MotionVector *MV[6][MBR+1][MBC+2], int gobsync)
           
{
  int i,j,k;
  int pmv0,pmv1,xoff,yoff;
  int curr_mb[16][16];
  int sad8 = INT_MAX, sad16, sad0;
  int newgob;
  MotionVector *f0,*f1,*f2,*f3,*f4;

  /* Do motion estimation and store result in array */
  for ( j = 0; j < lines/MB_SIZE; j++) {

    newgob = 0;
    if (gobsync && j%gobsync == 0) {
      newgob = 1;
    }

    for ( i = 0; i < pels/MB_SIZE; i++) {
      for (k = 0; k < 6; k++)
        MV[k][j+1][i+1] = (MotionVector *)malloc(sizeof(MotionVector));

      /* Integer pel search */
      f0 = MV[0][j+1][i+1];
      f1 = MV[1][j+1][i+1];
      f2 = MV[2][j+1][i+1];
      f3 = MV[3][j+1][i+1];
      f4 = MV[4][j+1][i+1];


      /* Here the PMV's are found using integer motion vectors */
      /* (NB should add explanation for this )*/
      FindPMV(MV,i+1,j+1,&pmv0,&pmv1,0,newgob,0);

      if (long_vectors) {
        xoff = pmv0/2; /* always divisable by two */
        yoff = pmv1/2;
      }
      else {
        xoff = yoff = 0;
      }
      
      MotionEstimation(curr, prev, i*MB_SIZE, j*MB_SIZE, 
               xoff, yoff, seek_dist, MV, &sad0);

      sad16 = f0->min_error;
      if (advanced)
        sad8 = f1->min_error + f2->min_error + f3->min_error + f4->min_error;

      f0->Mode = ChooseMode(curr,i*MB_SIZE,j*MB_SIZE, mmin(sad8,sad16));

      /* Half pel search */
      if (f0->Mode != MODE_INTRA) {
        FindMB(i*MB_SIZE,j*MB_SIZE ,curr, curr_mb);
        FindHalfPel(i*MB_SIZE,j*MB_SIZE,f0, prev_ipol, &curr_mb[0][0],16,0);
        sad16 = f0->min_error;

        if (advanced) {
          FindHalfPel(i*MB_SIZE,j*MB_SIZE,f1, prev_ipol, &curr_mb[0][0],8,0);
          FindHalfPel(i*MB_SIZE,j*MB_SIZE,f2, prev_ipol, &curr_mb[0][8],8,1);
          FindHalfPel(i*MB_SIZE,j*MB_SIZE,f3, prev_ipol, &curr_mb[8][0],8,2);
          FindHalfPel(i*MB_SIZE,j*MB_SIZE,f4, prev_ipol, &curr_mb[8][8],8,3);

          sad8 = f1->min_error +f2->min_error +f3->min_error +f4->min_error;
          sad8 += PREF_16_VEC;
          
          /* Choose Zero Vector, 8x8 or 16x16 vectors */
          if (sad0 < sad8 && sad0 < sad16) {
            f0->x = f0->y = 0;
            f0->x_half = f0->y_half = 0;
          }
          else {
            if (sad8 < sad16) 
              f0->Mode = MODE_INTER4V;
          }
        }
        else {
          /* Choose Zero Vector or 16x16 vectors */
          if (sad0 < sad16) {
            f0->x = f0->y = 0;
            f0->x_half = f0->y_half = 0;
          }
        }

      }
      else 
        for (k = 0; k < 5; k++)
          ZeroVec(MV[k][j+1][i+1]);

    }
  }

#ifdef PRINTMV
  fprintf(stdout,"Motion estimation\n");
  fprintf(stdout,"16x16 vectors:\n");

  for ( j = 0; j < lines/MB_SIZE; j++) {
    for ( i = 0; i < pels/MB_SIZE; i++) {
      if (MV[0][j+1][i+1]->Mode != MODE_INTRA)
        fprintf(stdout," %3d%3d",
        2*MV[0][j+1][i+1]->x + MV[0][j+1][i+1]->x_half,
        2*MV[0][j+1][i+1]->y + MV[0][j+1][i+1]->y_half);
      else
        fprintf(stdout,"  .  . ");
    }
    fprintf(stdout,"\n");
  }
  if (advanced) {
    fprintf(stdout,"8x8 vectors:\n");
    for (k = 1; k < 5; k++) {
      fprintf(stdout,"Block: %d\n", k-1);
      for ( j = 0; j < lines/MB_SIZE; j++) {
        for ( i = 0; i < pels/MB_SIZE; i++) {
          if (MV[0][j+1][i+1]->Mode != MODE_INTRA)
            fprintf(stdout," %3d%3d",
            2*MV[k][j+1][i+1]->x + MV[k][j+1][i+1]->x_half,
            2*MV[k][j+1][i+1]->y + MV[k][j+1][i+1]->y_half);
          else
            fprintf(stdout,"  .  . ");
        }
        fprintf(stdout,"\n");
      }
    }
  }
#endif
  return;
}


/**********************************************************************
 *
 *      Name:           MakeEdgeImage
 *	Description:    Copies edge pels for use with unrestricted
 *                      motion vector mode
 *	
 *	Input:	        pointer to source image, destination image
 *                      width, height, edge
 *	Returns:       
 *	Side effects:
 *
 ***********************************************************************/

void MakeEdgeImage(unsigned char *src, unsigned char *dst, int width,
           int height, int edge)
{
  int i,j;
  unsigned char *p1,*p2,*p3,*p4;
  unsigned char *o1,*o2,*o3,*o4;

  /* center image */
  p1 = dst;
  o1 = src;
  for (j = 0; j < height;j++) {
    memcpy(p1,o1,width);
    p1 += width + (edge<<1);
    o1 += width;
  }

  /* left and right edges */
  p1 = dst-1;
  o1 = src;
  for (j = 0; j < height;j++) {
    for (i = 0; i < edge; i++) {
      *(p1 - i) = *o1;
      *(p1 + width + i + 1) = *(o1 + width - 1);
    }
    p1 += width + (edge<<1);
    o1 += width;
  }    
    
  /* top and bottom edges */
  p1 = dst;
  p2 = dst + (width + (edge<<1))*(height-1);
  o1 = src;
  o2 = src + width*(height-1);
  for (j = 0; j < edge;j++) {
    p1 = p1 - (width + (edge<<1));
    p2 = p2 + (width + (edge<<1));
    for (i = 0; i < width; i++) {
      *(p1 + i) = *(o1 + i);
      *(p2 + i) = *(o2 + i);
    }
  }    

  /* corners */
  p1 = dst - (width+(edge<<1)) - 1;
  p2 = p1 + width + 1;
  p3 = dst + (width+(edge<<1))*(height)-1;
  p4 = p3 + width + 1;

  o1 = src;
  o2 = o1 + width - 1;
  o3 = src + width*(height-1);
  o4 = o3 + width - 1;
  for (j = 0; j < edge; j++) {
    for (i = 0; i < edge; i++) {
      *(p1 - i) = *o1;
      *(p2 + i) = *o2;
      *(p3 - i) = *o3;
      *(p4 + i) = *o4; 
    }
    p1 = p1 - (width + (edge<<1));
    p2 = p2 - (width + (edge<<1));
    p3 = p3 + width + (edge<<1);
    p4 = p4 + width + (edge<<1);
  }
}


/**********************************************************************
 *
 *      Name:           Clip
 *	Description:    clips recontructed data 0-255
 *	
 *	Input:	        pointer to recon. data structure
 *	Side effects:   data structure clipped
 *
 ***********************************************************************/

void Clip(MB_Structure *data)
{
  int m,n;

  for (n = 0; n < 16; n++) {
    for (m = 0; m < 16; m++) {
      data->lum[n][m] = mmin(255,mmax(0,data->lum[n][m]));
    }
  }
  for (n = 0; n < 8; n++) {
    for (m = 0; m < 8; m++) {
      data->Cr[n][m] = mmin(255,mmax(0,data->Cr[n][m]));
      data->Cb[n][m] = mmin(255,mmax(0,data->Cb[n][m]));
    }
  }
}

⌨️ 快捷键说明

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