1 /* rice.c
2  * Pseudo Rice encoding of an integer stream
3  * Copyright (C) 2000 Wayde Milas (wmilas@rarcoa.com)
4  *
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <math.h>
23 #include "types.h"
24 #include "rice.h"
25 #include "header.h"
26 #include "bits.h"
27 
rice_decode(KEXISBLOCKSTRUCT * kexisBlock,long * data,OPTIONSTRUCT * options,PCMBLOCKSTRUCT * pcmBlock,int kType)28 void rice_decode(KEXISBLOCKSTRUCT *kexisBlock, long *data,
29 	OPTIONSTRUCT *options, PCMBLOCKSTRUCT *pcmBlock, int kType)
30 {
31   long sign, loop, zeroes=0, newK;
32 	int	K;
33 
34 	K = get_K(&kexisBlock->predictor, kType, options->encoderVersion,
35 		options->kHistorySize);
36   sign = bit_suck(kexisBlock, 1, pcmBlock, options);
37 
38   loop = bit_suck(kexisBlock, 1, pcmBlock, options);
39   while(loop != 1) {
40     zeroes++;
41     loop = bit_suck(kexisBlock, 1, pcmBlock, options);
42   }
43 
44 	if(K != 0)
45   	*data = bit_suck(kexisBlock, K, pcmBlock, options);
46 	else
47 		*data = 0;
48 
49 	// move zeroes, which is an actual number now, into the prefix location,
50 	// ie, at the high end of the word.
51   zeroes <<= K;
52   *data = *data | zeroes;
53 
54 	newK = calc_newK(*data, &kexisBlock->predictor);
55 	update_K(&kexisBlock->predictor, newK, kType, options->encoderVersion,
56 		options->kHistorySize);
57 
58 	// collect K statistics if we need to
59 	if(options->verbose && !options->dec_stdout)
60 		collect_K_stats(&kexisBlock->predictor, newK, kType,
61 			options->encoderVersion);
62 
63  	if(sign == 0)
64     *data = -*data;
65 
66 	//debug_prints(0,0, kexisBlock->sumTotalSize,-1,-1,1);
67 	//debug_prints(*data,32, kexisBlock->sumTotalSize,0,0,0);
68 	//debug_prints(0,0, kexisBlock->sumTotalSize,-1,-1,1);
69 }
70 
rice_encode(KEXISBLOCKSTRUCT * kexisBlock,long data,OPTIONSTRUCT * options,PCMBLOCKSTRUCT * pcmBlock,int kType)71 void rice_encode(KEXISBLOCKSTRUCT *kexisBlock, long data,
72 	OPTIONSTRUCT *options, PCMBLOCKSTRUCT *pcmBlock, int kType)
73 {
74   long  holdData, loop, newK, remainder=0;
75 	int		K;
76 
77   K = get_K(&kexisBlock->predictor, kType, options->encoderVersion,
78 		options->kHistorySize);
79 
80 	// Push the first sign bit
81   if(data < 0)
82     push_bits(kexisBlock, 0, 1, options, pcmBlock);
83   else
84     push_bits(kexisBlock, 1, 1, options, pcmBlock);
85 
86   // Take the absolute value
87   holdData = abs(data);
88 	newK = calc_newK(holdData, &kexisBlock->predictor);
89 
90   // Figure out how many zeroes we need to pop in.
91   loop = holdData >> K;
92   while(loop != 0) {
93     push_bits(kexisBlock, 0, 1, options, pcmBlock);
94     loop--;
95   }
96 
97   //push a seperatior 1
98   push_bits(kexisBlock, 1, 1, options, pcmBlock);
99 
100 	// Only push bits if K is not 0.
101 	if(K != 0) {
102   // next put in the last K bits.
103   remainder = remainder | (holdData & ((1<<K) -1));
104   push_bits(kexisBlock, remainder, K, options, pcmBlock);
105 	}
106 
107 	//debug_prints(0,0, kexisBlock->debugBlockCount, -1, -1, 1);
108 	update_K(&kexisBlock->predictor, newK, kType, options->encoderVersion,
109 		options->kHistorySize);
110 
111 	// collect K statistics if we need to
112 	if(options->verbose)
113 		collect_K_stats(&kexisBlock->predictor, newK, kType,
114 			options->encoderVersion);
115 
116 	//if(DEBUG == 1 || PRED_DEBUG == 1)
117 	//	kexisBlock->debugBlockCount++;
118 }
119 
collect_K_stats(PREDICTORTABLE * pred,long newK,int kType,unsigned short encoderVersion)120 void collect_K_stats(PREDICTORTABLE *pred, long newK, int kType,
121 	unsigned short encoderVersion)
122 {
123 	if((encoderVersion == RICE_DUAL_K || encoderVersion == RICE_DUAL_K_BLOCK)
124 		&& kType == AVE) {
125 		if(newK < pred->aveLowK)
126 			pred->aveLowK = newK;
127 	  if(newK > pred->aveHighK)
128 	    pred->aveHighK = newK;
129 
130 		pred->aveCountK++;
131 		pred->aveSumK += newK;
132 	}
133 	else {
134 		if(newK < pred->midLowK)
135 			pred->midLowK = newK;
136 		if(newK > pred->midHighK)
137 			pred->midHighK = newK;
138 
139 		pred->midCountK++;
140 		pred->midSumK += newK;
141 	}
142 }
143 
get_K(PREDICTORTABLE * pred,int kType,unsigned short encoderVersion,int kHist)144 long get_K(PREDICTORTABLE *pred, int kType, unsigned short encoderVersion,
145 	int kHist)
146 {
147 	if(kType == MID) {
148 		if(encoderVersion == RICE_SINGLE_K || encoderVersion == RICE_DUAL_K)
149 			return pred->mid_K[0];
150 		else if(encoderVersion == RICE_DUAL_K_BLOCK) {
151 			return block_ave_K(pred->mid_K, kHist);
152 		}
153 	}
154 	else {
155 		if(encoderVersion == RICE_SINGLE_K)
156 			return pred->mid_K[0];
157 		else if(encoderVersion == RICE_DUAL_K)
158 			return pred->ave_K[0];
159 		else if(encoderVersion == RICE_DUAL_K_BLOCK) {
160 			return block_ave_K(pred->ave_K, kHist);
161 		}
162 	}
163 	return 0; // to stop compiler warnings
164 }
165 
block_ave_K(int table[],int kHist)166 int block_ave_K(int table[], int kHist)
167 {
168 	int sum =0;
169 	int	loop;
170 
171 	for(loop=0;loop<kHist;loop++) sum+= table[loop];
172 	//printf("%d %f\n", sum, ceil(sum/kHist));
173 	return ceil((float)sum/kHist);
174 }
175 
calc_newK(long holdData,PREDICTORTABLE * pred)176 long calc_newK(long holdData, PREDICTORTABLE *pred)
177 {
178 	long	newK;
179 
180 	if(holdData == 0)
181 		newK = 0;
182 	else
183 		//newK = log10(holdData)/pred->preLog10_2;
184 		newK = lookup_newK(holdData, pred);
185 
186 	return newK;
187 }
188 
update_K(PREDICTORTABLE * pred,long newK,int kType,unsigned short encoderVersion,int kHist)189 void update_K(PREDICTORTABLE *pred, long newK, int kType,
190 	unsigned short encoderVersion, int kHist)
191 {
192 	if(kType == MID) {
193 		if(encoderVersion == RICE_SINGLE_K || encoderVersion == RICE_DUAL_K)
194 			pred->mid_K[0] = ceil((pred->mid_K[0] + newK)/2.0);
195 		else if(encoderVersion == RICE_DUAL_K_BLOCK)
196 			pred->mid_K[pred->kBlockPointer] = newK;
197 	}
198 	else {
199 		if(encoderVersion == RICE_SINGLE_K)
200 			pred->mid_K[0] = ceil((pred->mid_K[0] + newK)/2.0);
201 		else if(encoderVersion == RICE_DUAL_K)
202 			pred->ave_K[0] = ceil((pred->ave_K[0] + newK)/2.0);
203 		else if(encoderVersion == RICE_DUAL_K_BLOCK) {
204 			pred->ave_K[pred->kBlockPointer] = newK;
205 			pred->kBlockPointer++;
206 			//pred->kBlockPointer = pred->kBlockPointer % kHist;
207 			if(pred->kBlockPointer == kHist)
208 				pred->kBlockPointer = 0;
209 		}
210 	}
211 }
212 
lookup_newK(long holdData,PREDICTORTABLE * pred)213 long lookup_newK(long holdData, PREDICTORTABLE *pred)
214 {
215 	if(holdData <= K_LOOKUP_SIZE) {
216 		if(pred->newKLookUP[holdData] != -1)
217 			return pred->newKLookUP[holdData];
218 		else {
219 			pred->newKLookUP[holdData] = log10(holdData)/pred->preLog10_2;
220 			return pred->newKLookUP[holdData];
221 		}
222 	}
223 	else
224 		return log10(holdData)/pred->preLog10_2;
225 }
226