putvlc.c
上传用户:hkgotone
上传日期:2013-02-17
资源大小:293k
文件大小:6k
源码类别:

Windows Mobile

开发平台:

C/C++

  1. /* putvlc.c, generation of variable length codes                            */
  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. #include "vlc.h"
  31. /* private prototypes */
  32. static void putDC _ANSI_ARGS_((sVLCtable *tab, int val));
  33. /* generate variable length code for luminance DC coefficient */
  34. void putDClum(val)
  35. int val;
  36. {
  37.   putDC(DClumtab,val);
  38. }
  39. /* generate variable length code for chrominance DC coefficient */
  40. void putDCchrom(val)
  41. int val;
  42. {
  43.   putDC(DCchromtab,val);
  44. }
  45. /* generate variable length code for DC coefficient (7.2.1) */
  46. static void putDC(tab,val)
  47. sVLCtable *tab;
  48. int val;
  49. {
  50.   int absval, size;
  51.   absval = (val<0) ? -val : val; /* abs(val) */
  52.   if (absval>2047 || (mpeg1 && absval>255))
  53.   {
  54.     /* should never happen */
  55.     sprintf(errortext,"DC value out of range (%d)n",val);
  56.     error(errortext);
  57.   }
  58.   /* compute dct_dc_size */
  59.   size = 0;
  60.   while (absval)
  61.   {
  62.     absval >>= 1;
  63.     size++;
  64.   }
  65.   /* generate VLC for dct_dc_size (Table B-12 or B-13) */
  66.   putbits(tab[size].code,tab[size].len);
  67.   /* append fixed length code (dc_dct_differential) */
  68.   if (size!=0)
  69.   {
  70.     if (val>=0)
  71.       absval = val;
  72.     else
  73.       absval = val + (1<<size) - 1; /* val + (2 ^ size) - 1 */
  74.     putbits(absval,size);
  75.   }
  76. }
  77. /* generate variable length code for first coefficient
  78.  * of a non-intra block (7.2.2.2) */
  79. void putACfirst(run,val)
  80. int run,val;
  81. {
  82.   if (run==0 && (val==1 || val==-1)) /* these are treated differently */
  83.     putbits(2|(val<0),2); /* generate '1s' (s=sign), (Table B-14, line 2) */
  84.   else
  85.     putAC(run,val,0); /* no difference for all others */
  86. }
  87. /* generate variable length code for other DCT coefficients (7.2.2) */
  88. void putAC(run,signed_level,vlcformat)
  89. int run,signed_level,vlcformat;
  90. {
  91.   int level, len;
  92.   VLCtable *ptab;
  93.   level = (signed_level<0) ? -signed_level : signed_level; /* abs(signed_level) */
  94.   /* make sure run and level are valid */
  95.   if (run<0 || run>63 || level==0 || level>2047 || (mpeg1 && level>255))
  96.   {
  97.     sprintf(errortext,"AC value out of range (run=%d, signed_level=%d)n",
  98.       run,signed_level);
  99.     error(errortext);
  100.   }
  101.   len = 0;
  102.   if (run<2 && level<41)
  103.   {
  104.     /* vlcformat selects either of Table B-14 / B-15 */
  105.     if (vlcformat)
  106.       ptab = &dct_code_tab1a[run][level-1];
  107.     else
  108.       ptab = &dct_code_tab1[run][level-1];
  109.     len = ptab->len;
  110.   }
  111.   else if (run<32 && level<6)
  112.   {
  113.     /* vlcformat selects either of Table B-14 / B-15 */
  114.     if (vlcformat)
  115.       ptab = &dct_code_tab2a[run-2][level-1];
  116.     else
  117.       ptab = &dct_code_tab2[run-2][level-1];
  118.     len = ptab->len;
  119.   }
  120.   if (len!=0) /* a VLC code exists */
  121.   {
  122.     putbits(ptab->code,len);
  123.     putbits(signed_level<0,1); /* sign */
  124.   }
  125.   else
  126.   {
  127.     /* no VLC for this (run, level) combination: use escape coding (7.2.2.3) */
  128.     putbits(1l,6); /* Escape */
  129.     putbits(run,6); /* 6 bit code for run */
  130.     if (mpeg1)
  131.     {
  132.       /* ISO/IEC 11172-2 uses a 8 or 16 bit code */
  133.       if (signed_level>127)
  134.         putbits(0,8);
  135.       if (signed_level<-127)
  136.         putbits(128,8);
  137.       putbits(signed_level,8);
  138.     }
  139.     else
  140.     {
  141.       /* ISO/IEC 13818-2 uses a 12 bit code, Table B-16 */
  142.       putbits(signed_level,12);
  143.     }
  144.   }
  145. }
  146. /* generate variable length code for macroblock_address_increment (6.3.16) */
  147. void putaddrinc(addrinc)
  148. int addrinc;
  149. {
  150.   while (addrinc>33)
  151.   {
  152.     putbits(0x08,11); /* macroblock_escape */
  153.     addrinc-= 33;
  154.   }
  155.   putbits(addrinctab[addrinc-1].code,addrinctab[addrinc-1].len);
  156. }
  157. /* generate variable length code for macroblock_type (6.3.16.1) */
  158. void putmbtype(pict_type,mb_type)
  159. int pict_type,mb_type;
  160. {
  161.   putbits(mbtypetab[pict_type-1][mb_type].code,
  162.           mbtypetab[pict_type-1][mb_type].len);
  163. }
  164. /* generate variable length code for motion_code (6.3.16.3) */
  165. void putmotioncode(motion_code)
  166. int motion_code;
  167. {
  168.   int abscode;
  169.   abscode = (motion_code>=0) ? motion_code : -motion_code; /* abs(motion_code) */
  170.   putbits(motionvectab[abscode].code,motionvectab[abscode].len);
  171.   if (motion_code!=0)
  172.     putbits(motion_code<0,1); /* sign, 0=positive, 1=negative */
  173. }
  174. /* generate variable length code for dmvector[t] (6.3.16.3), Table B-11 */
  175. void putdmv(dmv)
  176. int dmv;
  177. {
  178.   if (dmv==0)
  179.     putbits(0,1);
  180.   else if (dmv>0)
  181.     putbits(2,2);
  182.   else
  183.     putbits(3,2);
  184. }
  185. /* generate variable length code for coded_block_pattern (6.3.16.4)
  186.  *
  187.  * 4:2:2, 4:4:4 not implemented
  188.  */
  189. void putcbp(cbp)
  190. int cbp;
  191. {
  192.   putbits(cbptable[cbp].code,cbptable[cbp].len);
  193. }