tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

laplace.c (6257B)


      1 /* Copyright (c) 2007 CSIRO
      2   Copyright (c) 2007-2009 Xiph.Org Foundation
      3   Written by Jean-Marc Valin */
      4 /*
      5   Redistribution and use in source and binary forms, with or without
      6   modification, are permitted provided that the following conditions
      7   are met:
      8 
      9   - Redistributions of source code must retain the above copyright
     10   notice, this list of conditions and the following disclaimer.
     11 
     12   - Redistributions in binary form must reproduce the above copyright
     13   notice, this list of conditions and the following disclaimer in the
     14   documentation and/or other materials provided with the distribution.
     15 
     16   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     20   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     23   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     24   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     25   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     26   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include "config.h"
     31 #endif
     32 
     33 #include "laplace.h"
     34 #include "mathops.h"
     35 
     36 /* The minimum probability of an energy delta (out of 32768). */
     37 #define LAPLACE_LOG_MINP (0)
     38 #define LAPLACE_MINP (1<<LAPLACE_LOG_MINP)
     39 /* The minimum number of guaranteed representable energy deltas (in one
     40    direction). */
     41 #define LAPLACE_NMIN (16)
     42 
     43 /* When called, decay is positive and at most 11456. */
     44 static unsigned ec_laplace_get_freq1(unsigned fs0, int decay)
     45 {
     46   unsigned ft;
     47   ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;
     48   return ft*(opus_int32)(16384-decay)>>15;
     49 }
     50 
     51 void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)
     52 {
     53   unsigned fl;
     54   int val = *value;
     55   fl = 0;
     56   if (val)
     57   {
     58      int s;
     59      int i;
     60      s = -(val<0);
     61      val = (val+s)^s;
     62      fl = fs;
     63      fs = ec_laplace_get_freq1(fs, decay);
     64      /* Search the decaying part of the PDF.*/
     65      for (i=1; fs > 0 && i < val; i++)
     66      {
     67         fs *= 2;
     68         fl += fs+2*LAPLACE_MINP;
     69         fs = (fs*(opus_int32)decay)>>15;
     70      }
     71      /* Everything beyond that has probability LAPLACE_MINP. */
     72      if (!fs)
     73      {
     74         int di;
     75         int ndi_max;
     76         ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP;
     77         ndi_max = (ndi_max-s)>>1;
     78         di = IMIN(val - i, ndi_max - 1);
     79         fl += (2*di+1+s)*LAPLACE_MINP;
     80         fs = IMIN(LAPLACE_MINP, 32768-fl);
     81         *value = (i+di+s)^s;
     82      }
     83      else
     84      {
     85         fs += LAPLACE_MINP;
     86         fl += fs&~s;
     87      }
     88      celt_assert(fl+fs<=32768);
     89      celt_assert(fs>0);
     90   }
     91   ec_encode_bin(enc, fl, fl+fs, 15);
     92 }
     93 
     94 int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)
     95 {
     96   int val=0;
     97   unsigned fl;
     98   unsigned fm;
     99   fm = ec_decode_bin(dec, 15);
    100   fl = 0;
    101   if (fm >= fs)
    102   {
    103      val++;
    104      fl = fs;
    105      fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP;
    106      /* Search the decaying part of the PDF.*/
    107      while(fs > LAPLACE_MINP && fm >= fl+2*fs)
    108      {
    109         fs *= 2;
    110         fl += fs;
    111         fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15;
    112         fs += LAPLACE_MINP;
    113         val++;
    114      }
    115      /* Everything beyond that has probability LAPLACE_MINP. */
    116      if (fs <= LAPLACE_MINP)
    117      {
    118         int di;
    119         di = (fm-fl)>>(LAPLACE_LOG_MINP+1);
    120         val += di;
    121         fl += 2*di*LAPLACE_MINP;
    122      }
    123      if (fm < fl+fs)
    124         val = -val;
    125      else
    126         fl += fs;
    127   }
    128   celt_assert(fl<32768);
    129   celt_assert(fs>0);
    130   celt_assert(fl<=fm);
    131   celt_assert(fm<IMIN(fl+fs,32768));
    132   ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768);
    133   return val;
    134 }
    135 
    136 void ec_laplace_encode_p0(ec_enc *enc, int value, opus_uint16 p0, opus_uint16 decay)
    137 {
    138   int s;
    139   opus_uint16 sign_icdf[3];
    140   sign_icdf[0] = 32768-p0;
    141   sign_icdf[1] = sign_icdf[0]/2;
    142   sign_icdf[2] = 0;
    143   s = value == 0 ? 0 : (value > 0 ? 1 : 2);
    144   ec_enc_icdf16(enc, s, sign_icdf, 15);
    145   value = abs(value);
    146   if (value)
    147   {
    148      int i;
    149      opus_uint16 icdf[8];
    150      icdf[0] = IMAX(7, decay);
    151      for (i=1;i<7;i++)
    152      {
    153         icdf[i] = IMAX(7-i, (icdf[i-1] * (opus_int32)decay) >> 15);
    154      }
    155      icdf[7] = 0;
    156      value--;
    157      do {
    158         ec_enc_icdf16(enc, IMIN(value, 7), icdf, 15);
    159         value -= 7;
    160      } while (value >= 0);
    161   }
    162 }
    163 
    164 int ec_laplace_decode_p0(ec_dec *dec, opus_uint16 p0, opus_uint16 decay)
    165 {
    166   int s;
    167   int value;
    168   opus_uint16 sign_icdf[3];
    169   sign_icdf[0] = 32768-p0;
    170   sign_icdf[1] = sign_icdf[0]/2;
    171   sign_icdf[2] = 0;
    172   s = ec_dec_icdf16(dec, sign_icdf, 15);
    173   if (s==2) s = -1;
    174   if (s != 0)
    175   {
    176      int i;
    177      int v;
    178      opus_uint16 icdf[8];
    179      icdf[0] = IMAX(7, decay);
    180      for (i=1;i<7;i++)
    181      {
    182         icdf[i] = IMAX(7-i, (icdf[i-1] * (opus_int32)decay) >> 15);
    183      }
    184      icdf[7] = 0;
    185      value = 1;
    186      do {
    187         v = ec_dec_icdf16(dec, icdf, 15);
    188         value += v;
    189      } while (v == 7);
    190      return s*value;
    191   } else return 0;
    192 }
    193 
    194 #if 0
    195 
    196 #include <stdio.h>
    197 #define NB_VALS 10
    198 #define DATA_SIZE 10000
    199 int main() {
    200   ec_enc enc;
    201   ec_dec dec;
    202   unsigned char *ptr;
    203   int i;
    204   int decay, p0;
    205   int val[NB_VALS] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
    206   /*for (i=0;i<NB_VALS;i++) {
    207      val[i] = -log(rand()/(float)RAND_MAX);
    208      if (rand()%2) val[i] = -val[i];
    209   }*/
    210   p0 = 16000;
    211   decay = 16000;
    212   ptr = (unsigned char *)malloc(DATA_SIZE);
    213   ec_enc_init(&enc,ptr,DATA_SIZE);
    214   for (i=0;i<NB_VALS;i++) {
    215      printf("%d ", val[i]);
    216   }
    217   printf("\n");
    218   for (i=0;i<NB_VALS;i++) {
    219      ec_laplace_encode_p0(&enc, val[i], p0, decay);
    220   }
    221 
    222   ec_enc_done(&enc);
    223 
    224   ec_dec_init(&dec,ec_get_buffer(&enc),ec_range_bytes(&enc));
    225 
    226   for (i=0;i<NB_VALS;i++) {
    227      val[i] = ec_laplace_decode_p0(&dec, p0, decay);
    228   }
    229   for (i=0;i<NB_VALS;i++) {
    230      printf("%d ", val[i]);
    231   }
    232   printf("\n");
    233 }
    234 
    235 #endif