xref: /aosp_15_r20/external/flac/src/libFLAC/deduplication/bitreader_read_rice_signed_block.c (revision 600f14f40d737144c998e2ec7a483122d3776fbc)
1 {
2 	/* try and get br->consumed_words and br->consumed_bits into register;
3 	 * must remember to flush them back to *br before calling other
4 	 * bitreader functions that use them, and before returning */
5 	uint32_t cwords, words, lsbs, msbs, x, y, limit;
6 	uint32_t ucbits; /* keep track of the number of unconsumed bits in word */
7 	brword b;
8 	int *val, *end;
9 
10 	FLAC__ASSERT(0 != br);
11 	FLAC__ASSERT(0 != br->buffer);
12 	/* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
13 	FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
14 	FLAC__ASSERT(parameter < 32);
15 	/* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */
16 
17 	limit = UINT32_MAX >> parameter; /* Maximal msbs that can occur with residual bounded to int32_t */
18 
19 	val = vals;
20 	end = vals + nvals;
21 
22 	if(parameter == 0) {
23 		while(val < end) {
24 			/* read the unary MSBs and end bit */
25 			if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
26 				return false;
27 			/* Checking limit here would be overzealous: coding UINT32_MAX
28 			 * with parameter == 0 would take 4GiB */
29 			*val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1);
30 		}
31 
32 		return true;
33 	}
34 
35 	FLAC__ASSERT(parameter > 0);
36 
37 	cwords = br->consumed_words;
38 	words = br->words;
39 
40 	/* if we've not consumed up to a partial tail word... */
41 	if(cwords >= words) {
42 		x = 0;
43 		goto process_tail;
44 	}
45 
46 	ucbits = FLAC__BITS_PER_WORD - br->consumed_bits;
47 	b = br->buffer[cwords] << br->consumed_bits;  /* keep unconsumed bits aligned to left */
48 
49 	while(val < end) {
50 		/* read the unary MSBs and end bit */
51 		x = y = COUNT_ZERO_MSBS2(b);
52 		if(x == FLAC__BITS_PER_WORD) {
53 			x = ucbits;
54 			do {
55 				/* didn't find stop bit yet, have to keep going... */
56 				cwords++;
57 				if (cwords >= words)
58 					goto incomplete_msbs;
59 				b = br->buffer[cwords];
60 				y = COUNT_ZERO_MSBS2(b);
61 				x += y;
62 			} while(y == FLAC__BITS_PER_WORD);
63 		}
64 		b <<= y;
65 		b <<= 1; /* account for stop bit */
66 		ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD;
67 		msbs = x;
68 
69 		if(x > limit)
70 			return false;
71 
72 		/* read the binary LSBs */
73 		x = (FLAC__uint32)(b >> (FLAC__BITS_PER_WORD - parameter)); /* parameter < 32, so we can cast to 32-bit uint32_t */
74 		if(parameter <= ucbits) {
75 			ucbits -= parameter;
76 			b <<= parameter;
77 		} else {
78 			/* there are still bits left to read, they will all be in the next word */
79 			cwords++;
80 			if (cwords >= words)
81 				goto incomplete_lsbs;
82 			b = br->buffer[cwords];
83 			ucbits += FLAC__BITS_PER_WORD - parameter;
84 			x |= (FLAC__uint32)(b >> ucbits);
85 			b <<= FLAC__BITS_PER_WORD - ucbits;
86 		}
87 		lsbs = x;
88 
89 		/* compose the value */
90 		x = (msbs << parameter) | lsbs;
91 		*val++ = (int)(x >> 1) ^ -(int)(x & 1);
92 
93 		continue;
94 
95 		/* at this point we've eaten up all the whole words */
96 process_tail:
97 		do {
98 			if(0) {
99 incomplete_msbs:
100 				br->consumed_bits = 0;
101 				br->consumed_words = cwords;
102 			}
103 
104 			/* read the unary MSBs and end bit */
105 			if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
106 				return false;
107 			msbs += x;
108 			x = ucbits = 0;
109 
110 			if(0) {
111 incomplete_lsbs:
112 				br->consumed_bits = 0;
113 				br->consumed_words = cwords;
114 			}
115 
116 			/* read the binary LSBs */
117 			if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter - ucbits))
118 				return false;
119 			lsbs = x | lsbs;
120 
121 			/* compose the value */
122 			x = (msbs << parameter) | lsbs;
123 			*val++ = (int)(x >> 1) ^ -(int)(x & 1);
124 			x = 0;
125 
126 			cwords = br->consumed_words;
127 			words = br->words;
128 			ucbits = FLAC__BITS_PER_WORD - br->consumed_bits;
129 			b = cwords < br->capacity ? br->buffer[cwords] << br->consumed_bits : 0;
130 		} while(cwords >= words && val < end);
131 	}
132 
133 	if(ucbits == 0 && cwords < words) {
134 		/* don't leave the head word with no unconsumed bits */
135 		cwords++;
136 		ucbits = FLAC__BITS_PER_WORD;
137 	}
138 
139 	br->consumed_bits = FLAC__BITS_PER_WORD - ucbits;
140 	br->consumed_words = cwords;
141 
142 	return true;
143 }
144