1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer/* 263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 36c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * 46c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * Use of this source code is governed by a BSD-style license 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner * that can be found in the LICENSE file in the root of the source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner * tree. An additional intellectual property rights grant can be found 763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman * in the file PATENTS. All contributing project authors may 86c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * be found in the AUTHORS file in the root of the source tree. 96c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke */ 106c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 116c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "settings.h" 1263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman#include "arith_routines.h" 139a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 149a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 159a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson/* 169a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson * code symbols into arithmetic bytestream 176c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke */ 186c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaekevoid WebRtcIsac_EncHistMulti(Bitstr *streamdata, /* in-/output struct containing bitstream */ 196c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke const int *data, /* input: data vector */ 20551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ 21551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer const int N) /* input: data vector length */ 22551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer{ 235e4d8a5eca03c977ba01e061078a2d740ee6130aZonr Chang WebRtc_UWord32 W_lower, W_upper; 241f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer WebRtc_UWord32 W_upper_LSB, W_upper_MSB; 256c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke WebRtc_UWord8 *stream_ptr; 266c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke WebRtc_UWord8 *stream_ptr_carry; 276c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke WebRtc_UWord32 cdf_lo, cdf_hi; 286c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke int k; 296c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 306c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 316c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke /* point to beginning of stream buffer */ 326c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke stream_ptr = streamdata->stream + streamdata->stream_index; 33c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer W_upper = streamdata->W_upper; 346c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 35c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer for (k=N; k>0; k--) 366c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke { 37620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke /* fetch cdf_lower and cdf_upper from cdf tables */ 38620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke cdf_lo = (WebRtc_UWord32) *(*cdf + *data); 39c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer cdf_hi = (WebRtc_UWord32) *(*cdf++ + *data++ + 1); 40620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke 41c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer /* update interval */ 42620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke W_upper_LSB = W_upper & 0x0000FFFF; 43c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer W_upper_MSB = W_upper >> 16; 44620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke W_lower = W_upper_MSB * cdf_lo; 456c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke W_lower += (W_upper_LSB * cdf_lo) >> 16; 46757c1f9d87b516a1e3bc4cd678245b207ae9c559Brian Gaeke W_upper = W_upper_MSB * cdf_hi; 476c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke W_upper += (W_upper_LSB * cdf_hi) >> 16; 489a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 499a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson /* shift interval such that it begins at zero */ 509a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson W_upper -= ++W_lower; 519a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 529a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson /* add integer to bitstream */ 539a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson streamdata->streamval += W_lower; 549a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 559a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson /* handle carry */ 569a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson if (streamdata->streamval < W_lower) 579a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson { 589a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson /* propagate carry */ 599a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson stream_ptr_carry = stream_ptr; 609a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson while (!(++(*--stream_ptr_carry))); 619a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson } 629a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 636c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke /* renormalize interval, store most significant byte of streamval and update streamval */ 649a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */ 656c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke { 666c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke W_upper <<= 8; 676c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke *stream_ptr++ = (WebRtc_UWord8) (streamdata->streamval >> 24); 686c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke streamdata->streamval <<= 8; 696c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke } 706c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke } 716c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 726c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke /* calculate new stream_index */ 736c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke streamdata->stream_index = (int)(stream_ptr - streamdata->stream); 746c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke streamdata->W_upper = W_upper; 756c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 766c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke return; 776c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke} 78fe4591bfc2b147c10d6a7b1a5af56454fb78daceStephen Wilson 79314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson 806c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 819a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson/* 829a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson * function to decode more symbols from the arithmetic bytestream, using method of bisection 836c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * cdf tables should be of size 2^k-1 (which corresponds to an alphabet size of 2^k-2) 846c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke */ 85620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaekeint WebRtcIsac_DecHistBisectMulti(int *data, /* output: data vector */ 86620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke Bitstr *streamdata, /* in-/output struct containing bitstream */ 87e9f6f2c0492af8097166f1b7d62f131f20ca5714Brian Gaeke const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ 889a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson const WebRtc_UWord16 *cdf_size, /* input: array of cdf table sizes+1 (power of two: 2^k) */ 89c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer const int N) /* input: data vector length */ 90c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer{ 91c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer WebRtc_UWord32 W_lower, W_upper; 92620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke WebRtc_UWord32 W_tmp; 93620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke WebRtc_UWord32 W_upper_LSB, W_upper_MSB; 94620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke WebRtc_UWord32 streamval; 95c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer const WebRtc_UWord8 *stream_ptr; 96c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer const WebRtc_UWord16 *cdf_ptr; 97c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer int size_tmp; 98c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer int k; 99c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer 100c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer W_lower = 0; //to remove warning -DH 101c8f6c44af46554036084cba21a118266f5e26c0eMichael J. Spencer stream_ptr = streamdata->stream + streamdata->stream_index; 1029a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson W_upper = streamdata->W_upper; 1039a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson if (W_upper == 0) 1049a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson /* Should not be possible in normal operation */ 1059a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson return -2; 1069a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 107e9f6f2c0492af8097166f1b7d62f131f20ca5714Brian Gaeke if (streamdata->stream_index == 0) /* first time decoder is called for this stream */ 108620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke { 1096c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke /* read first word from bytestream */ 1106c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke streamval = *stream_ptr << 24; 1116c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke streamval |= *++stream_ptr << 16; 1126c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke streamval |= *++stream_ptr << 8; 1136c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke streamval |= *++stream_ptr; 1146c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke } else { 1156c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke streamval = streamdata->streamval; 1166c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke } 1176c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 1186c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke for (k=N; k>0; k--) 1196c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke { 1205af8f421b6412e52530608097e39d2602195629fDan Gohman /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ 1215af8f421b6412e52530608097e39d2602195629fDan Gohman W_upper_LSB = W_upper & 0x0000FFFF; 1225af8f421b6412e52530608097e39d2602195629fDan Gohman W_upper_MSB = W_upper >> 16; 1235af8f421b6412e52530608097e39d2602195629fDan Gohman 1245af8f421b6412e52530608097e39d2602195629fDan Gohman /* start halfway the cdf range */ 1255af8f421b6412e52530608097e39d2602195629fDan Gohman size_tmp = *cdf_size++ >> 1; 1266c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke cdf_ptr = *cdf + (size_tmp - 1); 1276c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 128fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* method of bisection */ 129fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer for ( ;; ) 130fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 131fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_tmp = W_upper_MSB * *cdf_ptr; 132fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_tmp += (W_upper_LSB * *cdf_ptr) >> 16; 133fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer size_tmp >>= 1; 134fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (size_tmp == 0) break; 135fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (streamval > W_tmp) 136fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 137fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_lower = W_tmp; 138fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer cdf_ptr += size_tmp; 139fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } else { 140fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper = W_tmp; 141fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer cdf_ptr -= size_tmp; 142fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 143fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 144fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (streamval > W_tmp) 145fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 146fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_lower = W_tmp; 147fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer *data++ = (int)(cdf_ptr - *cdf++); 148fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } else { 149fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper = W_tmp; 150fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer *data++ = (int)(cdf_ptr - *cdf++ - 1); 151fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 152fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 153fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* shift interval to start at zero */ 154fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper -= ++W_lower; 155fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 156fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* add integer to bitstream */ 157fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval -= W_lower; 158fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 159fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* renormalize interval and update streamval */ 160fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */ 161fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 162fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* read next byte from stream */ 163fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval = (streamval << 8) | *++stream_ptr; 164fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper <<= 8; 165fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 166fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 167fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (W_upper == 0) 168fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* Should not be possible in normal operation */ 169fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer return -2; 170fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 171fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 172fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 173fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 174fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamdata->stream_index = (int)(stream_ptr - streamdata->stream); 175fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamdata->W_upper = W_upper; 176fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamdata->streamval = streamval; 177fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 178fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 179fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* find number of bytes in original stream (determined by current interval width) */ 180fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if ( W_upper > 0x01FFFFFF ) 181fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer return streamdata->stream_index - 2; 182fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer else 183fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer return streamdata->stream_index - 1; 184fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer} 185fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 186fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 187fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 188fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer/* 189fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer * function to decode more symbols from the arithmetic bytestream, taking single step up or 190fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer * down at a time 191fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer * cdf tables can be of arbitrary size, but large tables may take a lot of iterations 192fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer */ 193fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencerint WebRtcIsac_DecHistOneStepMulti(int *data, /* output: data vector */ 194fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer Bitstr *streamdata, /* in-/output struct containing bitstream */ 195fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer const WebRtc_UWord16 **cdf, /* input: array of cdf arrays */ 196fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer const WebRtc_UWord16 *init_index, /* input: vector of initial cdf table search entries */ 197fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer const int N) /* input: data vector length */ 198fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer{ 199fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer WebRtc_UWord32 W_lower, W_upper; 200fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer WebRtc_UWord32 W_tmp; 201fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer WebRtc_UWord32 W_upper_LSB, W_upper_MSB; 202fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer WebRtc_UWord32 streamval; 203fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer const WebRtc_UWord8 *stream_ptr; 204fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer const WebRtc_UWord16 *cdf_ptr; 205fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer int k; 206fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 207fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 208fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer stream_ptr = streamdata->stream + streamdata->stream_index; 209fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper = streamdata->W_upper; 210fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (W_upper == 0) 211fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* Should not be possible in normal operation */ 212fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer return -2; 213fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 214fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (streamdata->stream_index == 0) /* first time decoder is called for this stream */ 215fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 216fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* read first word from bytestream */ 217fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval = *stream_ptr << 24; 218fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval |= *++stream_ptr << 16; 219fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval |= *++stream_ptr << 8; 220fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval |= *++stream_ptr; 221fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } else { 222fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval = streamdata->streamval; 223fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 224fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 225fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 226fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer for (k=N; k>0; k--) 227fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 228fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ 229fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper_LSB = W_upper & 0x0000FFFF; 230fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper_MSB = W_upper >> 16; 231fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 232fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* start at the specified table entry */ 233fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer cdf_ptr = *cdf + (*init_index++); 234fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_tmp = W_upper_MSB * *cdf_ptr; 235fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_tmp += (W_upper_LSB * *cdf_ptr) >> 16; 236fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (streamval > W_tmp) 237fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 238fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer for ( ;; ) 239fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 240fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_lower = W_tmp; 241fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (cdf_ptr[0]==65535) 242fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* range check */ 243fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer return -3; 244fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_tmp = W_upper_MSB * *++cdf_ptr; 245fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_tmp += (W_upper_LSB * *cdf_ptr) >> 16; 246fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (streamval <= W_tmp) break; 247fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 248fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper = W_tmp; 249fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer *data++ = (int)(cdf_ptr - *cdf++ - 1); 250fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } else { 251fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer for ( ;; ) 25268ef0382e4efe4a4c06e47a53a275b873ba0cff4Evandro Menezes { 253fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper = W_tmp; 254fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer --cdf_ptr; 255fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (cdf_ptr<*cdf) { 256fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* range check */ 257fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer return -3; 258fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 259fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_tmp = W_upper_MSB * *cdf_ptr; 260fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_tmp += (W_upper_LSB * *cdf_ptr) >> 16; 261fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if (streamval > W_tmp) break; 262fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 263fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_lower = W_tmp; 264fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer *data++ = (int)(cdf_ptr - *cdf++); 265fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 266fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 267fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* shift interval to start at zero */ 268fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper -= ++W_lower; 269fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* add integer to bitstream */ 270fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval -= W_lower; 271fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 272fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* renormalize interval and update streamval */ 273fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */ 274fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer { 27572062f5744557e270a38192554c3126ea5f97434Tim Northover /* read next byte from stream */ 276fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamval = (streamval << 8) | *++stream_ptr; 277fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer W_upper <<= 8; 278fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 279fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer } 280fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 281fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamdata->stream_index = (int)(stream_ptr - streamdata->stream); 282fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamdata->W_upper = W_upper; 283fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer streamdata->streamval = streamval; 284fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 285fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer 286fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer /* find number of bytes in original stream (determined by current interval width) */ 287fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer if ( W_upper > 0x01FFFFFF ) 288fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer return streamdata->stream_index - 2; 289fc61a23506fdad8f38e3437d741a4108339abcfeMichael J. Spencer else 2906fccaafd8be0eb7619b5a210387b0d1254ef4174Rafael Espindola return streamdata->stream_index - 1; 2916c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke} 2926c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke