putmpg.c
上传用户:ma_junhua
上传日期:2008-04-11
资源大小:2752k
文件大小:4k
开发平台:

C/C++

  1. /* putmpg.c, block and motion vector encoding routines                      */
  2. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  3. /*
  4.  * Disclaimer of Warranty
  5.  *
  6.  * These software programs are available to the user without any license fee or
  7.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  8.  * any and all warranties, whether express, implied, or statuary, including any
  9.  * implied warranties or merchantability or of fitness for a particular
  10.  * purpose.  In no event shall the copyright-holder be liable for any
  11.  * incidental, punitive, or consequential damages of any kind whatsoever
  12.  * arising from the use of these programs.
  13.  *
  14.  * This disclaimer of warranty extends to the user of these programs and user's
  15.  * customers, employees, agents, transferees, successors, and assigns.
  16.  *
  17.  * The MPEG Software Simulation Group does not represent or warrant that the
  18.  * programs furnished hereunder are free of infringement of any third-party
  19.  * patents.
  20.  *
  21.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  22.  * are subject to royalty fees to patent holders.  Many of these patents are
  23.  * general enough such that they are unavoidable regardless of implementation
  24.  * design.
  25.  *
  26.  */
  27. #include <stdio.h>
  28. #include "config.h"
  29. #include "global.h"
  30. /* generate variable length codes for an intra-coded block (6.2.6, 6.3.17) */
  31. void putintrablk(blk,cc)
  32. short *blk;
  33. int cc;
  34. {
  35.   int n, dct_diff, run, signed_level;
  36.   /* DC coefficient (7.2.1) */
  37.   dct_diff = blk[0] - dc_dct_pred[cc]; /* difference to previous block */
  38.   dc_dct_pred[cc] = blk[0];
  39.   if (cc==0)
  40.     putDClum(dct_diff);
  41.   else
  42.     putDCchrom(dct_diff);
  43.   /* AC coefficients (7.2.2) */
  44.   run = 0;
  45.   for (n=1; n<64; n++)
  46.   {
  47.     /* use appropriate entropy scanning pattern */
  48.     signed_level = blk[(altscan ? alternate_scan : zig_zag_scan)[n]];
  49.     if (signed_level!=0)
  50.     {
  51.       putAC(run,signed_level,intravlc);
  52.       run = 0;
  53.     }
  54.     else
  55.       run++; /* count zero coefficients */
  56.   }
  57.   /* End of Block -- normative block punctuation */
  58.   if (intravlc)
  59.     putbits(6,4); /* 0110 (Table B-15) */
  60.   else
  61.     putbits(2,2); /* 10 (Table B-14) */
  62. }
  63. /* generate variable length codes for a non-intra-coded block (6.2.6, 6.3.17) */
  64. void putnonintrablk(blk)
  65. short *blk;
  66. {
  67.   int n, run, signed_level, first;
  68.   run = 0;
  69.   first = 1;
  70.   for (n=0; n<64; n++)
  71.   {
  72.     /* use appropriate entropy scanning pattern */
  73.     signed_level = blk[(altscan ? alternate_scan : zig_zag_scan)[n]];
  74.     if (signed_level!=0)
  75.     {
  76.       if (first)
  77.       {
  78.         /* first coefficient in non-intra block */
  79.         putACfirst(run,signed_level);
  80.         first = 0;
  81.       }
  82.       else
  83.         putAC(run,signed_level,0);
  84.       run = 0;
  85.     }
  86.     else
  87.       run++; /* count zero coefficients */
  88.   }
  89.   /* End of Block -- normative block punctuation  */
  90.   putbits(2,2);
  91. }
  92. /* generate variable length code for a motion vector component (7.6.3.1) */
  93. void putmv(dmv,f_code)
  94. int dmv,f_code;
  95. {
  96.   int r_size, f, vmin, vmax, dv, temp, motion_code, motion_residual;
  97.   r_size = f_code - 1; /* number of fixed length code ('residual') bits */
  98.   f = 1<<r_size;
  99.   vmin = -16*f; /* lower range limit */
  100.   vmax = 16*f - 1; /* upper range limit */
  101.   dv = 32*f;
  102.   /* fold vector difference into [vmin...vmax] */
  103.   if (dmv>vmax)
  104.     dmv-= dv;
  105.   else if (dmv<vmin)
  106.     dmv+= dv;
  107.   /* check value */
  108.   if (dmv<vmin || dmv>vmax)
  109.     if (!quiet)
  110.       fprintf(stderr,"invalid motion vectorn");
  111.   /* split dmv into motion_code and motion_residual */
  112.   temp = ((dmv<0) ? -dmv : dmv) + f - 1;
  113.   motion_code = temp>>r_size;
  114.   if (dmv<0)
  115.     motion_code = -motion_code;
  116.   motion_residual = temp & (f-1);
  117.   putmotioncode(motion_code); /* variable length code */
  118.   if (r_size!=0 && motion_code!=0)
  119.     putbits(motion_residual,r_size); /* fixed length code */
  120. }