quant.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:16k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /* $Id: quant.cpp,v 1.2 2001/04/19 18:32:10 wmay Exp $ */
  2. /****************************************************************************/
  3. /*   MPEG4 Visual Texture Coding (VTC) Mode Software                        */
  4. /*                                                                          */
  5. /*   This software was jointly developed by the following participants:     */
  6. /*                                                                          */
  7. /*   Single-quant,  multi-quant and flow control                            */
  8. /*   are provided by  Sarnoff Corporation                                   */
  9. /*     Iraj Sodagar   (iraj@sarnoff.com)                                    */
  10. /*     Hung-Ju Lee    (hjlee@sarnoff.com)                                   */
  11. /*     Paul Hatrack   (hatrack@sarnoff.com)                                 */
  12. /*     Shipeng Li     (shipeng@sarnoff.com)                                 */
  13. /*     Bing-Bing Chai (bchai@sarnoff.com)                                   */
  14. /*     B.S. Srinivas  (bsrinivas@sarnoff.com)                               */
  15. /*                                                                          */
  16. /*   Bi-level is provided by Texas Instruments                              */
  17. /*     Jie Liang      (liang@ti.com)                                        */
  18. /*                                                                          */
  19. /*   Shape Coding is provided by  OKI Electric Industry Co., Ltd.           */
  20. /*     Zhixiong Wu    (sgo@hlabs.oki.co.jp)                                 */
  21. /*     Yoshihiro Ueda (yueda@hlabs.oki.co.jp)                               */
  22. /*     Toshifumi Kanamaru (kanamaru@hlabs.oki.co.jp)                        */
  23. /*                                                                          */
  24. /*   OKI, Sharp, Sarnoff, TI and Microsoft contributed to bitstream         */
  25. /*   exchange and bug fixing.                                               */
  26. /*                                                                          */
  27. /*                                                                          */
  28. /* In the course of development of the MPEG-4 standard, this software       */
  29. /* module is an implementation of a part of one or more MPEG-4 tools as     */
  30. /* specified by the MPEG-4 standard.                                        */
  31. /*                                                                          */
  32. /* The copyright of this software belongs to ISO/IEC. ISO/IEC gives use     */
  33. /* of the MPEG-4 standard free license to use this  software module or      */
  34. /* modifications thereof for hardware or software products claiming         */
  35. /* conformance to the MPEG-4 standard.                                      */
  36. /*                                                                          */
  37. /* Those intending to use this software module in hardware or software      */
  38. /* products are advised that use may infringe existing  patents. The        */
  39. /* original developers of this software module and their companies, the     */
  40. /* subsequent editors and their companies, and ISO/IEC have no liability    */
  41. /* and ISO/IEC have no liability for use of this software module or         */
  42. /* modification thereof in an implementation.                               */
  43. /*                                                                          */
  44. /* Permission is granted to MPEG members to use, copy, modify,              */
  45. /* and distribute the software modules ( or portions thereof )              */
  46. /* for standardization activity within ISO/IEC JTC1/SC29/WG11.              */
  47. /*                                                                          */
  48. /* Copyright 1995, 1996, 1997, 1998 ISO/IEC                                 */
  49. /****************************************************************************/
  50. /************************************************************/
  51. /*     Sarnoff Very Low Bit Rate Still Image Coder          */
  52. /*     Copyright 1995, 1996, 1997, 1998 Sarnoff Corporation */
  53. /************************************************************/
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #include "basic.hpp"
  57. #include "dataStruct.hpp"
  58. #include "quant.hpp"
  59. /* sign */
  60. #define SGN(x) (((x)<0) ? -1 : 1)
  61. /* Integer rounding */
  62. #define IROUND(n,d) ( ((n)/(d)) + (((n)%(d) > (d-1)/2) || (n)<(d))) 
  63. /* Integer ceiling */
  64. #define ICEIL(n,d) ( ((n)/(d)) + ((n)%(d)!=0 || (n)<(d)) ) 
  65. /* For partitionType bit field processing */
  66. #define MASK_fromReduced  ((UChar)'1')
  67. #define MASK_fromDeadZone ((UChar)'2')
  68. #define SET_fromReduced(x)  ((x) |= MASK_fromReduced)
  69. #define SET_fromDeadZone(x) ((x) |= MASK_fromDeadZone)
  70. #define CLR_fromReduced(x)  ((x) &= ~(MASK_fromReduced))
  71. #define CLR_fromDeadZone(x) ((x) &= ~(MASK_fromDeadZone))
  72. #define fromReduced(x)  ((x) & MASK_fromReduced)
  73. #define fromDeadZone(x) (((x) & MASK_fromDeadZone)>>1)
  74. /*------------------------- QUANTIZATION --------------------------*/
  75. /* 
  76.    Function:
  77.    ---------
  78.    initQuantSingleStage - Initialization of the single-stage quantizer for
  79.      a given value.
  80.    Arguments:
  81.    ----------
  82.    quantState *state - PoInter to the state data structure.
  83.    Int *statePrevQ - PoInter to previous quantized value state.
  84.    Int initialValue - Value which is to be quantized.
  85.    Return Value:
  86.    -------------
  87.    <None>
  88.    Description:
  89.    ------------
  90.    This must be called prior to single-stage quantization. A seperate
  91.    state structure must be kept for each value that is quantized in parallel.
  92.    Single-stage quantization is just successive calls to quantSingleStage.
  93.    For each value,  need only be called once, before the first call to 
  94.    quantSingleStage.
  95. */
  96. Void CVTCCommon::initQuantSingleStage(quantState *state, Int *statePrevQ, Int initialVal)
  97. {
  98.   state->residualValue = initialVal;
  99.   state->partitionType = 0x2; /* fromReduced = 0 and fromDeadZone  = 1 */
  100.   *statePrevQ          = 0;
  101. }
  102. /* 
  103.    Function:
  104.    ---------
  105.    quantSingleStage - Single-stage quantizer.
  106.    Arguments:
  107.    ----------
  108.    Int Q - Quantization value. Represents desired quantization level size.
  109.    quantState *state - State of quantizer.
  110.    Int *statePrevQ - PoInter to previous quantized value state.
  111.    Int updatePrevQ - 0 means don't update the statePrevQ variable. !0 means
  112.      update it.
  113.    Return Value:
  114.    -------------
  115.    New Q index.
  116.    Description:
  117.    ------------
  118.    initQuantSingleStage must be called prior to using this function the
  119.    first time for a given value. It will compute the new quantization index
  120.    based on the current state associated with the value.
  121. */
  122. Int CVTCEncoder::quantSingleStage(Int Q, quantState *state, Int *statePrevQ,
  123.      Int updatePrevQ)
  124. {
  125.   Int refLevs;    /* how many refinement levels in new stage */
  126.   Int QIndex;     /* new quantization index to return for this stage */
  127.   /*--------------- INITIAL QUANTIZATION STAGE -------------------*/
  128.   if (*statePrevQ==0)
  129.   {
  130.     QIndex = state->residualValue/Q;
  131.     /* update state */
  132.     if (QIndex)
  133.       state->residualValue = abs(state->residualValue) - (abs(QIndex)*Q);
  134.     CLR_fromReduced(state->partitionType);
  135.     if (QIndex)
  136.       CLR_fromDeadZone(state->partitionType);
  137.     else
  138.       SET_fromDeadZone(state->partitionType);
  139.  
  140.     if (updatePrevQ)
  141.       *statePrevQ = Q;
  142.     return QIndex;
  143.   }
  144.   /*--------------- NON-INITIAL QUANTIZATION STAGES -------------------*/
  145.   /* get the number of refinement levels from lastQUsed state */
  146.   refLevs = IROUND(*statePrevQ,Q);
  147.   /* Catch condition where there's no refinement being done.
  148.      State information is not changed.
  149.   */
  150.   if (refLevs<=1)
  151.     QIndex = 0;
  152.   else
  153.   {
  154.     Int inDeadZone;  /* are we still in the dead zone */
  155.     Int lastQUsed;   /* The "real" Q value last used */
  156.     Int val;         /* value of number to be quantized */
  157.     Int lastLevSize; /* Size of quantization level used last */
  158.     Int newQUsed, newStateQ;
  159.     Int excess;
  160.     /* Initialize the last quant value used */
  161.     lastQUsed = *statePrevQ;
  162.     
  163.     /* update new Q value state */
  164.     newStateQ = newQUsed = ICEIL(lastQUsed,refLevs);
  165.     if (updatePrevQ)
  166.       *statePrevQ = newStateQ;
  167.     /* Get last level size */
  168.     lastLevSize = lastQUsed-fromReduced(state->partitionType);
  169.     /* check if a reduced level can span the last level */
  170.     if (refLevs*(newQUsed-1) >= lastLevSize)
  171.     {
  172.       --newQUsed;
  173.       /* might overshoot (?) but can't reduce anymore */
  174.       excess=0;
  175.     }
  176.     else
  177.       /* get excess (overshoot) */
  178.       excess=lastLevSize-refLevs*newQUsed;
  179.     /* Set dead zone indicator */
  180.     inDeadZone = fromDeadZone(state->partitionType);
  181.     
  182.     /* Set value of leftovers from last pass */
  183.     val=state->residualValue;
  184.     /*--- Calculate QIndex. Update residualValue and fromReduced states ---*/
  185.     if (excess==0)
  186.     {
  187.       QIndex = val/newQUsed;
  188.       if (newQUsed < newStateQ)
  189. SET_fromReduced(state->partitionType);
  190.       else
  191. CLR_fromReduced(state->partitionType);
  192.       
  193.       if (QIndex)
  194. state->residualValue -= QIndex*newQUsed;
  195.     }
  196.     else
  197.     {
  198.       Int reducedParStart; /* Where the reduced partition starts (magnitude)
  199.     */
  200.       Int reducedIdx;
  201.       reducedParStart = newQUsed*(refLevs+excess);
  202.       if (abs(val) >= reducedParStart)
  203.       {
  204. SET_fromReduced(state->partitionType);
  205. QIndex = SGN(state->residualValue)*(refLevs+excess);
  206. state->residualValue -= QIndex*newQUsed;
  207. --newQUsed;
  208. reducedIdx = 
  209.   SGN(state->residualValue) * (abs(val)-reducedParStart) / newQUsed;
  210. QIndex += reducedIdx;
  211. state->residualValue -= reducedIdx*newQUsed;
  212.       }
  213.       else
  214.       {
  215. CLR_fromReduced(state->partitionType);
  216. QIndex = val/newQUsed;
  217. state->residualValue -= QIndex*newQUsed;
  218.       }
  219.     }
  220.     
  221.     if (inDeadZone && QIndex)
  222.     {
  223.       /* We have the sign info so all residual values from here on in are 
  224.  positive */
  225.       state->residualValue = abs(state->residualValue);
  226.       CLR_fromDeadZone(state->partitionType);
  227.     }
  228.   }
  229.   return QIndex;
  230. }
  231. /*--------------- INVERSE QUANTIZATION --------------------------*/
  232. /* 
  233.    Function:
  234.    ---------
  235.    initInvQuantSingleStage - Initialization of the single-stage inverse
  236.      quantizer for a given Q index.
  237.    Arguments:
  238.    ----------
  239.    quantState *state - PoInter to the state data structure.
  240.    Int *statePrevQ - PoInter to previous quantized value state.
  241.    Return Value:
  242.    -------------
  243.    <None>
  244.    Description:
  245.    ------------
  246.    This must be called prior to single-stage inverse quantization. A seperate
  247.    state structure must be kept for each value that is quantized in parallel.
  248.    Single-stage inverse quantization is just successive calls to 
  249.    invQuantSingleStage. For each value,  need only be called once, before
  250.    the first call to invQuantSingleStage.
  251. */
  252. Void CVTCCommon::initInvQuantSingleStage(quantState *state, Int *statePrevQ)
  253. {
  254.   state->residualValue = 0;
  255.   state->partitionType = 0x2; /* fromReduced = 0 and fromDeadZone  = 1 */
  256.   *statePrevQ          = 0;
  257. }
  258. #define QLEVMID(q) (((q))/2)   // 1124
  259. /* Mapping of start of quantization level, sign, and quantization level size
  260.    to specific value.
  261. */
  262. #define GETVAL(start, sgn, q) ((start) 
  263.        ? ((start) + (sgn)*QLEVMID((q))) 
  264.        : 0)
  265. /* 
  266.    Function:
  267.    ---------
  268.    invQuantSingleStage - Single-stage inverse quantizer.
  269.    Arguments:
  270.    ----------
  271.    QIndex - Quantized value for this stage.
  272.    Q     - Quantization value. Represents desired quantization level size.
  273.    state - State of quantizer.
  274.    Int *statePrevQ - PoInter to previous quantized value state.
  275.    Int updatePrevQ - 0 means don't update the statePrevQ variable. !0 means
  276.      update it.
  277.    Return Value:
  278.    -------------
  279.    Inverse quantization value for this stage.
  280.    Description:
  281.    ------------
  282.    initInvQuantSingleStage must be called prior to using this function the
  283.    first time for a given value. It will compute the new, updated value
  284.    based on the current index and state associated with the value.
  285. */
  286. Int CVTCCommon::invQuantSingleStage(Int QIndex, Int Q, quantState *state, Int *statePrevQ,
  287. Int updatePrevQ)
  288. {
  289.   Int refLevs; /* how many refinement levels in new stage */
  290.   Int val;     /* new value to return for this stage */
  291.   Int sgn;
  292.   /*--------------- INITIAL QUANTIZATION STAGE -------------------*/
  293.   if (*statePrevQ==0)
  294.   {
  295.     val = QIndex*Q + SGN(QIndex)*(QIndex ? QLEVMID(Q) : 0);
  296.     /* update state */
  297.     state->residualValue = QIndex*Q;
  298.     CLR_fromReduced(state->partitionType);
  299.     if (QIndex)
  300.       CLR_fromDeadZone(state->partitionType);
  301.     else
  302.       SET_fromDeadZone(state->partitionType);
  303.     if (updatePrevQ)
  304.       *statePrevQ = Q;
  305.     return val;
  306.   }
  307.   /*--------------- NON-INITIAL QUANTIZATION STAGES -------------------*/
  308.   /* get the number of refinement levels from lastQUsed state */
  309.   refLevs = IROUND(*statePrevQ,Q);
  310.   /* Catch condition where there's no refinement being done.
  311.      State information is not changed.
  312.   */
  313.   sgn = (state->residualValue < 0 || QIndex < 0) ? -1 : 1;      
  314.   if (refLevs<=1)
  315.     val = GETVAL(state->residualValue,sgn,*statePrevQ);
  316.   else
  317.   {
  318.     Int inDeadZone;  /* are we still in the dead zone */
  319.     Int lastQUsed;   /* The "real" Q value last used */
  320.     Int lastLevSize; /* Size of quantization level used last */
  321.     Int newQUsed, newStateQ;
  322.     Int excess;
  323.     Int absQIndex;
  324.     /* Initialize the last quant value used */
  325.     lastQUsed = *statePrevQ;
  326.     
  327.     /* update new Q value state */
  328.     newStateQ = newQUsed = ICEIL(lastQUsed,refLevs);
  329.     if (updatePrevQ)
  330.       *statePrevQ = newStateQ;
  331.     /* Get last level size */
  332.     lastLevSize = lastQUsed-fromReduced(state->partitionType);
  333.     /* check if a reduced level can span the last level */
  334.     if (refLevs*(newQUsed-1) >= lastLevSize)
  335.     {
  336.       --newQUsed;
  337.       /* might overshoot (?) but can't reduce anymore */
  338.       excess=0;
  339. #if 1
  340.       if (lastLevSize-refLevs*newQUsed)
  341. fprintf(stderr,"Excess in reduced partitionn");
  342. #endif
  343.     }
  344.     else
  345.       /* get excess (overshoot) */
  346.       excess=lastLevSize-refLevs*newQUsed;
  347.     /* Set dead zone indicator */
  348.     inDeadZone = fromDeadZone(state->partitionType);
  349.     /*--- Calculate val. Update residualValue and fromReduced states ---*/
  350.     absQIndex = abs(QIndex);
  351.     if (excess==0)
  352.     {
  353.       if (newQUsed < newStateQ)
  354. SET_fromReduced(state->partitionType);
  355.       else
  356. CLR_fromReduced(state->partitionType);
  357.       state->residualValue += sgn*absQIndex*newQUsed;
  358.     }
  359.     else
  360.     {
  361.       Int reducedIdx;
  362.       Int fullLevs;
  363.       fullLevs = refLevs+excess;
  364.       if (absQIndex >= fullLevs)
  365.       {
  366. SET_fromReduced(state->partitionType);
  367. state->residualValue += sgn*fullLevs*newQUsed;
  368. --newQUsed;
  369. reducedIdx = absQIndex-fullLevs;
  370. state->residualValue += sgn*reducedIdx*newQUsed;
  371.       }
  372.       else
  373.       {
  374. CLR_fromReduced(state->partitionType);
  375. state->residualValue += sgn*absQIndex*newQUsed;
  376.       }
  377.     }
  378.     val = GETVAL(state->residualValue, sgn, newQUsed);
  379.     
  380.     if (inDeadZone && QIndex)
  381.       CLR_fromDeadZone(state->partitionType);
  382.   }
  383.   return val;
  384. }
  385. /*--------- DERIVED QUANTIZATION VALUES AND REFINEMENT LEVELS ----------*/
  386. /* 
  387.    Function:
  388.    ---------
  389.    quantRefLev - Get the number of quantization levels for a given stage and
  390.      the revised Q value.
  391.    Arguments:
  392.    ----------
  393.    Int curQ - Current input Q value.
  394.    Int *lastQUsed - last, revised, Q value. Will be updated.
  395.    Int whichQ - Quantization stage.
  396.    Return Value:
  397.    -------------
  398.    The number of refinement quantization levels.
  399.    Description:
  400.    ------------
  401.    quantRefLev will return the number of refinement quantization levels
  402.    at stage whichQ based on the last Q value used and the current input Q
  403.    value. It will also update the revised Q value by overwriting the argument
  404.    lastQUsed.
  405. */
  406. Int CVTCCommon::quantRefLev(Int curQ, Int *lastQUsed, Int whichQ)
  407. {
  408.   Int refLevs;
  409.   Int newQUsed;
  410.   /* get the number of refinement levels */
  411.   refLevs = IROUND(*lastQUsed,curQ);
  412.     
  413.   if (whichQ==0 || refLevs>1)
  414.   {
  415.     /* get new level size */
  416.     newQUsed = ICEIL(*lastQUsed,refLevs);
  417.     /* update the last quant value used */
  418.     *lastQUsed = newQUsed;
  419.   }
  420.   return refLevs;
  421. }