19e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/*
29e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
39e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
49e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *  Use of this source code is governed by a BSD-style license
59e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *  that can be found in the LICENSE file in the root of the source
69e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *  tree. An additional intellectual property rights grant can be found
79e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *  in the file PATENTS.  All contributing project authors may
89e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *  be found in the AUTHORS file in the root of the source tree.
99e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/*
129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * arith_routinshist.c
139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * This C file contains arithmetic encoding and decoding.
159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "arith_routins.h"
199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/****************************************************************************
229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * WebRtcIsacfix_EncHistMulti(...)
239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Encode the histogram interval
259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Input:
279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - streamData        : in-/output struct containing bitstream
289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - data              : data vector
299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - cdf               : array of cdf arrays
309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - lenData           : data vector length
319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return value             : 0 if ok
339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *                            <0 if error detected
349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgint WebRtcIsacfix_EncHistMulti(Bitstr_enc *streamData,
369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                              const WebRtc_Word16 *data,
379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                              const WebRtc_UWord16 **cdf,
389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                              const WebRtc_Word16 lenData)
399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32 W_lower;
419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32 W_upper;
429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32 W_upper_LSB;
439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32 W_upper_MSB;
449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord16 *streamPtr;
459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord16 negCarry;
469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord16 *maxStreamPtr;
479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord16 *streamPtrCarry;
489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32 cdfLo;
499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32 cdfHi;
509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  int k;
519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  /* point to beginning of stream buffer
549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   * and set maximum streamPtr value */
559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamPtr = streamData->stream + streamData->stream_index;
569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1;
579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  W_upper = streamData->W_upper;
599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  for (k = lenData; k > 0; k--)
619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  {
629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* fetch cdf_lower and cdf_upper from cdf tables */
639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    cdfLo = (WebRtc_UWord32) *(*cdf + (WebRtc_UWord32)*data);
649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    cdfHi = (WebRtc_UWord32) *(*cdf++ + (WebRtc_UWord32)*data++ + 1);
659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* update interval */
679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper_LSB = W_upper & 0x0000FFFF;
689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16);
699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_lower = WEBRTC_SPL_UMUL(W_upper_MSB, cdfLo);
709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_lower += WEBRTC_SPL_UMUL_RSFT16(W_upper_LSB, cdfLo);
719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper = WEBRTC_SPL_UMUL(W_upper_MSB, cdfHi);
729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper += WEBRTC_SPL_UMUL_RSFT16(W_upper_LSB, cdfHi);
739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* shift interval such that it begins at zero */
759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper -= ++W_lower;
769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* add integer to bitstream */
789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    streamData->streamval += W_lower;
799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* handle carry */
819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (streamData->streamval < W_lower)
829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    {
839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* propagate carry */
849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      streamPtrCarry = streamPtr;
859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (streamData->full == 0) {
869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        negCarry = *streamPtrCarry;
879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        negCarry += 0x0100;
889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        *streamPtrCarry = negCarry;
899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        while (!(negCarry))
909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        {
914d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org          negCarry = *--streamPtrCarry;
924d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org          negCarry++;
939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          *streamPtrCarry = negCarry;
949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        }
959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      } else {
969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        while ( !(++(*--streamPtrCarry)) );
979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* renormalize interval, store most significant byte of streamval and update streamval
1019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org     * W_upper < 2^24 */
1029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    while ( !(W_upper & 0xFF000000) )
1039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    {
1049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
1059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (streamData->full == 0) {
1069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        *streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
1079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamData->full = 1;
1089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      } else {
1099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32(
1109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
1119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamData->full = 0;
1129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
1139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if( streamPtr > maxStreamPtr ) {
1159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
1169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
1173847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      streamData->streamval = WEBRTC_SPL_LSHIFT_W32(streamData->streamval, 8);
1183847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
1193847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
1209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  /* calculate new stream_index */
1229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamData->stream_index = streamPtr - streamData->stream;
1239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamData->W_upper = W_upper;
1249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  return 0;
1269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
1279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/****************************************************************************
1309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * WebRtcIsacfix_DecHistBisectMulti(...)
1319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
1329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Function to decode more symbols from the arithmetic bytestream, using
1339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * method of bisection cdf tables should be of size 2^k-1 (which corresponds
1349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * to an alphabet size of 2^k-2)
1359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
1369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Input:
1379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - streamData        : in-/output struct containing bitstream
1389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - cdf               : array of cdf arrays
1399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - cdfSize           : array of cdf table sizes+1 (power of two: 2^k)
1409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - lenData           : data vector length
1419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
1429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Output:
1439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - data              : data vector
1449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
1459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return value             : number of bytes in the stream
1469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *                            <0 if error detected
1479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
1489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgWebRtc_Word16 WebRtcIsacfix_DecHistBisectMulti(WebRtc_Word16 *data,
1499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                              Bitstr_dec *streamData,
1509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                              const WebRtc_UWord16 **cdf,
1517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                                              const WebRtc_UWord16 *cdfSize,
1527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                                              const WebRtc_Word16 lenData)
1537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org{
154ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  WebRtc_UWord32    W_lower = 0;
155ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  WebRtc_UWord32    W_upper;
1569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    W_tmp;
1579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    W_upper_LSB;
1589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    W_upper_MSB;
1599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    streamval;
16031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  const WebRtc_UWord16 *streamPtr;
16131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  const WebRtc_UWord16 *cdfPtr;
16231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  WebRtc_Word16     sizeTmp;
1639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  int             k;
1649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamPtr = streamData->stream + streamData->stream_index;
1679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  W_upper = streamData->W_upper;
1689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  /* Error check: should not be possible in normal operation */
1709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if (W_upper == 0) {
1719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    return -2;
1729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
1739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  /* first time decoder is called for this stream */
1759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if (streamData->stream_index == 0)
1769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  {
1779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* read first word from bytestream */
1789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    streamval = WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)*streamPtr++, 16);
1799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    streamval |= *streamPtr++;
1809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  } else {
1819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    streamval = streamData->streamval;
1829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
1839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  for (k = lenData; k > 0; k--)
1859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  {
1864d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
1874d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    W_upper_LSB = W_upper & 0x0000FFFF;
1889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16);
1899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* start halfway the cdf range */
1919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    sizeTmp = WEBRTC_SPL_RSHIFT_W16(*cdfSize++, 1);
1929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    cdfPtr = *cdf + (sizeTmp - 1);
1939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* method of bisection */
1959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    for ( ;; )
1969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    {
1979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
1989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
1999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      sizeTmp = WEBRTC_SPL_RSHIFT_W16(sizeTmp, 1);
2009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (sizeTmp == 0) {
2019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        break;
2029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
2039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (streamval > W_tmp)
2059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      {
2069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        W_lower = W_tmp;
2079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        cdfPtr += sizeTmp;
2089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      } else {
2099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        W_upper = W_tmp;
2109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        cdfPtr -= sizeTmp;
2119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
2129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
2139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (streamval > W_tmp)
2149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    {
2159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      W_lower = W_tmp;
2169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      *data++ = cdfPtr - *cdf++;
2179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    } else {
2189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      W_upper = W_tmp;
2199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      *data++ = cdfPtr - *cdf++ - 1;
2209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
2219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* shift interval to start at zero */
2239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper -= ++W_lower;
2249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* add integer to bitstream */
2263847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    streamval -= W_lower;
2273847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
2283847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    /* renormalize interval and update streamval */
2293847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    /* W_upper < 2^24 */
2303847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    while ( !(W_upper & 0xFF000000) )
2319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    {
2329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* read next byte from stream */
2339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (streamData->full == 0) {
2349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) |
2359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            (*streamPtr++ & 0x00FF);
2369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamData->full = 1;
2379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      } else {
2389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) |
2399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            WEBRTC_SPL_RSHIFT_W16(*streamPtr, 8);
2409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamData->full = 0;
2419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
2429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
2439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
2449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* Error check: should not be possible in normal operation */
2479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (W_upper == 0) {
2489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      return -2;
2499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
2509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
2529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamData->stream_index = streamPtr - streamData->stream;
2549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamData->W_upper = W_upper;
2559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamData->streamval = streamval;
2569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if ( W_upper > 0x01FFFFFF ) {
2589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    return (streamData->stream_index*2 - 3 + !streamData->full);
2599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  } else {
2609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    return (streamData->stream_index*2 - 2 + !streamData->full);
2619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
2629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
2639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/****************************************************************************
2669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * WebRtcIsacfix_DecHistOneStepMulti(...)
2679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
2689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Function to decode more symbols from the arithmetic bytestream, taking
2699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * single step up or down at a time.
2709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * cdf tables can be of arbitrary size, but large tables may take a lot of
2719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * iterations.
2729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
2739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Input:
2749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - streamData        : in-/output struct containing bitstream
2759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - cdf               : array of cdf arrays
2769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - initIndex         : vector of initial cdf table search entries
2779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - lenData           : data vector length
2789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
2799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Output:
2809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *      - data              : data vector
2819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
2829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return value             : number of bytes in original stream
2839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *                            <0 if error detected
2849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
2854d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.orgWebRtc_Word16 WebRtcIsacfix_DecHistOneStepMulti(WebRtc_Word16 *data,
2864d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org                                               Bitstr_dec *streamData,
2879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                               const WebRtc_UWord16 **cdf,
2889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                               const WebRtc_UWord16 *initIndex,
2899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                               const WebRtc_Word16 lenData)
2909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
2919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    W_lower;
2929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    W_upper;
2939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    W_tmp;
2949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    W_upper_LSB;
2959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    W_upper_MSB;
2969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  WebRtc_UWord32    streamval;
2979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  const WebRtc_UWord16 *streamPtr;
2989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  const WebRtc_UWord16 *cdfPtr;
2999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  int             k;
3009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamPtr = streamData->stream + streamData->stream_index;
3039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  W_upper = streamData->W_upper;
3049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  /* Error check: Should not be possible in normal operation */
3059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if (W_upper == 0) {
3069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    return -2;
3079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
3089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  /* Check if it is the first time decoder is called for this stream */
3109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if (streamData->stream_index == 0)
3119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  {
3129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* read first word from bytestream */
3139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    streamval = WEBRTC_SPL_LSHIFT_U32(*streamPtr++, 16);
3149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    streamval |= *streamPtr++;
3159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  } else {
3169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    streamval = streamData->streamval;
3179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
3189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  for (k = lenData; k > 0; k--)
3209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  {
3219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
3229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper_LSB = W_upper & 0x0000FFFF;
3239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper_MSB = WEBRTC_SPL_RSHIFT_U32(W_upper, 16);
3249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* start at the specified table entry */
3269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    cdfPtr = *cdf + (*initIndex++);
3279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
3289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
3299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (streamval > W_tmp)
3319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    {
3329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      for ( ;; )
3339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      {
3349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        W_lower = W_tmp;
3359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        /* range check */
3379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        if (cdfPtr[0] == 65535) {
3389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          return -3;
3399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        }
3409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *++cdfPtr);
3429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
3439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3443847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        if (streamval <= W_tmp) {
3453847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          break;
3463847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        }
3473847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      }
3483847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      W_upper = W_tmp;
3493847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      *data++ = cdfPtr - *cdf++ - 1;
3503847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    } else {
3519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      for ( ;; )
3529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      {
3539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        W_upper = W_tmp;
3547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        --cdfPtr;
3557b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
3567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        /* range check */
3577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        if (cdfPtr < *cdf) {
3587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          return -3;
3597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
3607b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
3617b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
3627b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
3639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        if (streamval > W_tmp) {
3659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          break;
3669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        }
3679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
3689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      W_lower = W_tmp;
3699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      *data++ = cdfPtr - *cdf++;
3709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
3719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* shift interval to start at zero */
3739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    W_upper -= ++W_lower;
3749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* add integer to bitstream */
3769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    streamval -= W_lower;
3779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* renormalize interval and update streamval */
3799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    /* W_upper < 2^24 */
3809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    while ( !(W_upper & 0xFF000000) )
3819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    {
3829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* read next byte from stream */
3839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (streamData->full == 0) {
3849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | (*streamPtr++ & 0x00FF);
3859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamData->full = 1;
3869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      } else {
3879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | (*streamPtr >> 8);
3889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org        streamData->full = 0;
3899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
3909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
3919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    }
3929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
3939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamData->stream_index = streamPtr - streamData->stream;
3959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamData->W_upper = W_upper;
3969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  streamData->streamval = streamval;
3979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  /* find number of bytes in original stream (determined by current interval width) */
3999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if ( W_upper > 0x01FFFFFF ) {
4009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    return (streamData->stream_index*2 - 3 + !streamData->full);
4019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  } else {
4024d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    return (streamData->stream_index*2 - 2 + !streamData->full);
4039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
4049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
4059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org