Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /******************************************************************** |
michael@0 | 2 | * * |
michael@0 | 3 | * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * |
michael@0 | 4 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
michael@0 | 5 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
michael@0 | 6 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
michael@0 | 7 | * * |
michael@0 | 8 | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * |
michael@0 | 9 | * by the Xiph.Org Foundation http://www.xiph.org/ * |
michael@0 | 10 | * * |
michael@0 | 11 | ******************************************************************** |
michael@0 | 12 | |
michael@0 | 13 | function: floor backend 0 implementation |
michael@0 | 14 | last mod: $Id: floor0.c 19031 2013-12-03 19:20:50Z tterribe $ |
michael@0 | 15 | |
michael@0 | 16 | ********************************************************************/ |
michael@0 | 17 | |
michael@0 | 18 | #include <stdlib.h> |
michael@0 | 19 | #include <string.h> |
michael@0 | 20 | #include <math.h> |
michael@0 | 21 | #include <ogg/ogg.h> |
michael@0 | 22 | #include "vorbis/codec.h" |
michael@0 | 23 | #include "codec_internal.h" |
michael@0 | 24 | #include "registry.h" |
michael@0 | 25 | #include "lpc.h" |
michael@0 | 26 | #include "lsp.h" |
michael@0 | 27 | #include "codebook.h" |
michael@0 | 28 | #include "scales.h" |
michael@0 | 29 | #include "misc.h" |
michael@0 | 30 | #include "os.h" |
michael@0 | 31 | |
michael@0 | 32 | #include "misc.h" |
michael@0 | 33 | #include <stdio.h> |
michael@0 | 34 | |
michael@0 | 35 | typedef struct { |
michael@0 | 36 | int ln; |
michael@0 | 37 | int m; |
michael@0 | 38 | int **linearmap; |
michael@0 | 39 | int n[2]; |
michael@0 | 40 | |
michael@0 | 41 | vorbis_info_floor0 *vi; |
michael@0 | 42 | |
michael@0 | 43 | long bits; |
michael@0 | 44 | long frames; |
michael@0 | 45 | } vorbis_look_floor0; |
michael@0 | 46 | |
michael@0 | 47 | |
michael@0 | 48 | /***********************************************/ |
michael@0 | 49 | |
michael@0 | 50 | static void floor0_free_info(vorbis_info_floor *i){ |
michael@0 | 51 | vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; |
michael@0 | 52 | if(info){ |
michael@0 | 53 | memset(info,0,sizeof(*info)); |
michael@0 | 54 | _ogg_free(info); |
michael@0 | 55 | } |
michael@0 | 56 | } |
michael@0 | 57 | |
michael@0 | 58 | static void floor0_free_look(vorbis_look_floor *i){ |
michael@0 | 59 | vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; |
michael@0 | 60 | if(look){ |
michael@0 | 61 | |
michael@0 | 62 | if(look->linearmap){ |
michael@0 | 63 | |
michael@0 | 64 | if(look->linearmap[0])_ogg_free(look->linearmap[0]); |
michael@0 | 65 | if(look->linearmap[1])_ogg_free(look->linearmap[1]); |
michael@0 | 66 | |
michael@0 | 67 | _ogg_free(look->linearmap); |
michael@0 | 68 | } |
michael@0 | 69 | memset(look,0,sizeof(*look)); |
michael@0 | 70 | _ogg_free(look); |
michael@0 | 71 | } |
michael@0 | 72 | } |
michael@0 | 73 | |
michael@0 | 74 | static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){ |
michael@0 | 75 | codec_setup_info *ci=vi->codec_setup; |
michael@0 | 76 | int j; |
michael@0 | 77 | |
michael@0 | 78 | vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info)); |
michael@0 | 79 | info->order=oggpack_read(opb,8); |
michael@0 | 80 | info->rate=oggpack_read(opb,16); |
michael@0 | 81 | info->barkmap=oggpack_read(opb,16); |
michael@0 | 82 | info->ampbits=oggpack_read(opb,6); |
michael@0 | 83 | info->ampdB=oggpack_read(opb,8); |
michael@0 | 84 | info->numbooks=oggpack_read(opb,4)+1; |
michael@0 | 85 | |
michael@0 | 86 | if(info->order<1)goto err_out; |
michael@0 | 87 | if(info->rate<1)goto err_out; |
michael@0 | 88 | if(info->barkmap<1)goto err_out; |
michael@0 | 89 | if(info->numbooks<1)goto err_out; |
michael@0 | 90 | |
michael@0 | 91 | for(j=0;j<info->numbooks;j++){ |
michael@0 | 92 | info->books[j]=oggpack_read(opb,8); |
michael@0 | 93 | if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out; |
michael@0 | 94 | if(ci->book_param[info->books[j]]->maptype==0)goto err_out; |
michael@0 | 95 | if(ci->book_param[info->books[j]]->dim<1)goto err_out; |
michael@0 | 96 | } |
michael@0 | 97 | return(info); |
michael@0 | 98 | |
michael@0 | 99 | err_out: |
michael@0 | 100 | floor0_free_info(info); |
michael@0 | 101 | return(NULL); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | /* initialize Bark scale and normalization lookups. We could do this |
michael@0 | 105 | with static tables, but Vorbis allows a number of possible |
michael@0 | 106 | combinations, so it's best to do it computationally. |
michael@0 | 107 | |
michael@0 | 108 | The below is authoritative in terms of defining scale mapping. |
michael@0 | 109 | Note that the scale depends on the sampling rate as well as the |
michael@0 | 110 | linear block and mapping sizes */ |
michael@0 | 111 | |
michael@0 | 112 | static void floor0_map_lazy_init(vorbis_block *vb, |
michael@0 | 113 | vorbis_info_floor *infoX, |
michael@0 | 114 | vorbis_look_floor0 *look){ |
michael@0 | 115 | if(!look->linearmap[vb->W]){ |
michael@0 | 116 | vorbis_dsp_state *vd=vb->vd; |
michael@0 | 117 | vorbis_info *vi=vd->vi; |
michael@0 | 118 | codec_setup_info *ci=vi->codec_setup; |
michael@0 | 119 | vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX; |
michael@0 | 120 | int W=vb->W; |
michael@0 | 121 | int n=ci->blocksizes[W]/2,j; |
michael@0 | 122 | |
michael@0 | 123 | /* we choose a scaling constant so that: |
michael@0 | 124 | floor(bark(rate/2-1)*C)=mapped-1 |
michael@0 | 125 | floor(bark(rate/2)*C)=mapped */ |
michael@0 | 126 | float scale=look->ln/toBARK(info->rate/2.f); |
michael@0 | 127 | |
michael@0 | 128 | /* the mapping from a linear scale to a smaller bark scale is |
michael@0 | 129 | straightforward. We do *not* make sure that the linear mapping |
michael@0 | 130 | does not skip bark-scale bins; the decoder simply skips them and |
michael@0 | 131 | the encoder may do what it wishes in filling them. They're |
michael@0 | 132 | necessary in some mapping combinations to keep the scale spacing |
michael@0 | 133 | accurate */ |
michael@0 | 134 | look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap)); |
michael@0 | 135 | for(j=0;j<n;j++){ |
michael@0 | 136 | int val=floor( toBARK((info->rate/2.f)/n*j) |
michael@0 | 137 | *scale); /* bark numbers represent band edges */ |
michael@0 | 138 | if(val>=look->ln)val=look->ln-1; /* guard against the approximation */ |
michael@0 | 139 | look->linearmap[W][j]=val; |
michael@0 | 140 | } |
michael@0 | 141 | look->linearmap[W][j]=-1; |
michael@0 | 142 | look->n[W]=n; |
michael@0 | 143 | } |
michael@0 | 144 | } |
michael@0 | 145 | |
michael@0 | 146 | static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd, |
michael@0 | 147 | vorbis_info_floor *i){ |
michael@0 | 148 | vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; |
michael@0 | 149 | vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look)); |
michael@0 | 150 | |
michael@0 | 151 | (void)vd; |
michael@0 | 152 | |
michael@0 | 153 | look->m=info->order; |
michael@0 | 154 | look->ln=info->barkmap; |
michael@0 | 155 | look->vi=info; |
michael@0 | 156 | |
michael@0 | 157 | look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap)); |
michael@0 | 158 | |
michael@0 | 159 | return look; |
michael@0 | 160 | } |
michael@0 | 161 | |
michael@0 | 162 | static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ |
michael@0 | 163 | vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; |
michael@0 | 164 | vorbis_info_floor0 *info=look->vi; |
michael@0 | 165 | int j,k; |
michael@0 | 166 | |
michael@0 | 167 | int ampraw=oggpack_read(&vb->opb,info->ampbits); |
michael@0 | 168 | if(ampraw>0){ /* also handles the -1 out of data case */ |
michael@0 | 169 | long maxval=(1<<info->ampbits)-1; |
michael@0 | 170 | float amp=(float)ampraw/maxval*info->ampdB; |
michael@0 | 171 | int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); |
michael@0 | 172 | |
michael@0 | 173 | if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */ |
michael@0 | 174 | codec_setup_info *ci=vb->vd->vi->codec_setup; |
michael@0 | 175 | codebook *b=ci->fullbooks+info->books[booknum]; |
michael@0 | 176 | float last=0.f; |
michael@0 | 177 | |
michael@0 | 178 | /* the additional b->dim is a guard against any possible stack |
michael@0 | 179 | smash; b->dim is provably more than we can overflow the |
michael@0 | 180 | vector */ |
michael@0 | 181 | float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1)); |
michael@0 | 182 | |
michael@0 | 183 | if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop; |
michael@0 | 184 | for(j=0;j<look->m;){ |
michael@0 | 185 | for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last; |
michael@0 | 186 | last=lsp[j-1]; |
michael@0 | 187 | } |
michael@0 | 188 | |
michael@0 | 189 | lsp[look->m]=amp; |
michael@0 | 190 | return(lsp); |
michael@0 | 191 | } |
michael@0 | 192 | } |
michael@0 | 193 | eop: |
michael@0 | 194 | return(NULL); |
michael@0 | 195 | } |
michael@0 | 196 | |
michael@0 | 197 | static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i, |
michael@0 | 198 | void *memo,float *out){ |
michael@0 | 199 | vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; |
michael@0 | 200 | vorbis_info_floor0 *info=look->vi; |
michael@0 | 201 | |
michael@0 | 202 | floor0_map_lazy_init(vb,info,look); |
michael@0 | 203 | |
michael@0 | 204 | if(memo){ |
michael@0 | 205 | float *lsp=(float *)memo; |
michael@0 | 206 | float amp=lsp[look->m]; |
michael@0 | 207 | |
michael@0 | 208 | /* take the coefficients back to a spectral envelope curve */ |
michael@0 | 209 | vorbis_lsp_to_curve(out, |
michael@0 | 210 | look->linearmap[vb->W], |
michael@0 | 211 | look->n[vb->W], |
michael@0 | 212 | look->ln, |
michael@0 | 213 | lsp,look->m,amp,(float)info->ampdB); |
michael@0 | 214 | return(1); |
michael@0 | 215 | } |
michael@0 | 216 | memset(out,0,sizeof(*out)*look->n[vb->W]); |
michael@0 | 217 | return(0); |
michael@0 | 218 | } |
michael@0 | 219 | |
michael@0 | 220 | /* export hooks */ |
michael@0 | 221 | const vorbis_func_floor floor0_exportbundle={ |
michael@0 | 222 | NULL,&floor0_unpack,&floor0_look,&floor0_free_info, |
michael@0 | 223 | &floor0_free_look,&floor0_inverse1,&floor0_inverse2 |
michael@0 | 224 | }; |