1: //------------------------------------------------------------------------------
2: // Copyright (c) Microsoft Corporation. All rights reserved.
3: //------------------------------------------------------------------------------
4:
5: using System;
6: using System.Collections.Generic;
7:
8: namespace Microsoft.Protocols.TestTools.StackSdk.RemoteDesktop.Rdpegfx
9: {
10: /// <summary>
11: /// Simplified Run-Length (SRL) Eecoder
12: /// </summary>
13: public class SRLEncoder
14: {
15: // Constants used within the RLGR1/RLGR3 algorithm
16:
17: const int KPMAX = 80; // max value for kp or krp
18: const int LSGR = 3; // shift count to convert kp to k
19: const int UP_GR = 4; // increase in kp after a zero run in RL mode
20: const int DN_GR = 6; // decrease in kp after a nonzero symbol in RL mode
21: const int UQ_GR = 3; // increase in kp after nonzero symbol in GR mode
22: const int DQ_GR = 3; // decrease in kp after zero symbol in GR mode
23:
24: short[] inputData;
25: int[] InputDataBitLen;
26: int nextInputIdx;
27: int bufferOffset = 0;
28: byte[] pBuffer;
29:
30: /// <summary>
31: /// Do ALGR encode to the input data.
32: /// </summary>
33: /// <param name="inputArr">Input data to be encoded.</param>
34: /// <param name="mode">The ALGR mode, can be RLGR1 or RLGR3.</param>
35: /// <returns>The encoded data.</returns>
36: public byte[] Encode(short[] inputArr, int[] bitLenArr)
37: {
38: inputData = inputArr;
39: InputDataBitLen = bitLenArr;
40: nextInputIdx = 0;
41: bufferOffset = 0; //offset&0xFFFFFFF8 = byte offset, offset&0x7 = bit offset
42: pBuffer = new byte[inputArr.Length];
43: //bitStrm = new BitStream();
44:
45: SRL_Encode();
46:
47:
48: int numbytes = bufferOffset >> 3;
49: int bitOffset = bufferOffset & 7;
50: if (bitOffset != 0) numbytes++;
51:
52: byte[] encodedBytes = new byte[numbytes];
53: Array.Copy(pBuffer, encodedBytes, encodedBytes.Length);
54: return encodedBytes;
55:
56: //return bitStrm.ToBytes();
57: }
58:
59: //
60: // Returns the next coefficient (a signed int) to encode, from the input stream
61: //
62: int GetNextInput(out int bitLen)
63: {
64: bitLen = InputDataBitLen[nextInputIdx];
65: return (int)inputData[nextInputIdx++];
66: }
67:
68: bool hasMoreData()
69: {
70: return (nextInputIdx <= inputData.Length - 1);
71: }
72:
73: //
74: // Emit bitPattern to the output bitstream.
75: // The bitPattern value represents a bit sequence that is generated by shifting
76: // new bits in from the right. If we take the binary representation of bitPattern,
77: // with N(numBits-1) being the leftmost bit position and 0 being the rightmost bit position,
78: // the mapping of bitPattern to the output bytes is as follows:
79: //
80: // bitPattern[N..0] -> byte[MSB..LSB] .. byte[MSB..LSB]
81: //
82: public void OutputBits(
83: int numBits, // number of bits in bitPattern
84: int bitPattern // bit pattern
85: )
86: {
87: int patternOffset = numBits - 1;
88:
89: while (patternOffset >= 0)
90: {
91: int bit = ((bitPattern & (1 << patternOffset)) != 0) ? 1 : 0;
92: OutputBit(1, bit);
93: patternOffset--;
94: }
95:
96: }
97:
98: //
99: // Emit a bit (0 or 1), count number of times, to the output bitstream
100: //
101: void OutputBit(
102: int count, // number of times to emit the bit
103: int bit // 0 or 1
104: )
105: {
106: if (count == 0) return;
107:
108: //bitStrm.WriteBits(count, bit == 1 ? true : false);
109:
110:
111: for (int i = 0; i < count; i++)
112: {
113: int bitOffset = bufferOffset & 7;
114: int bufferBoundary = bufferOffset >> 3;
115: if (bit != 0) // bit 1
116: {
117: pBuffer[bufferBoundary] |= (byte)(1 << (7 - bitOffset));
118: }
119: else
120: {
121: pBuffer[bufferBoundary] &= (byte)(0xFF - ((byte)(1 << (7 - bitOffset))));
122: }
123: bufferOffset++;
124: }
125:
126: }
127:
128: //
129: // Update the passed parameter and clamp it to the range [0,KPMAX]
130: // Return the value of parameter right-shifted by LSGR
131: //
132: int UpdateParam(
133: ref int param, // parameter to update
134: int deltaP // update delta
135: )
136: {
137: param += deltaP;
138: if (param > KPMAX) param = KPMAX;
139: if (param < 0) param = 0;
140: return (param >> LSGR);
141: }
142:
143: //
144: // Routine that outputs a stream of RLGR1/RLGR3-encoded bits
145: //
146: void SRL_Encode(
147: )
148: {
149: // initialize the parameters
150: int k = 1;
151: int kp = 1 << LSGR;
152: //int kr = 1;
153: //int krp = 1 << LSGR;
154:
155: // process all the input coefficients
156: while (hasMoreData())
157: {
158: int input;
159: int bitLen;
160:
161: //if (k != 0)
162: {
163: // RUN-LENGTH MODE
164:
165: // collect the run of zeros in the input stream
166: int numZeros = 0;
167: while ((input = GetNextInput(out bitLen)) == 0)
168: {
169: ++numZeros;
170: if (!hasMoreData()) break;
171: }
172:
173: // emit output zebros
174: int runmax = 1 << k;
175: while (numZeros >= runmax)
176: {
177: OutputBit(1, 0); // output a zero bit
178: numZeros -= runmax;
179: k = UpdateParam(ref kp, UP_GR); // update kp, k
180: runmax = 1 << k;
181: }
182:
183: // output a 1 to terminate runs
184: OutputBit(1, 1);
185:
186: // output the remaining run length using k bits
187: OutputBits(k, numZeros);
188:
189: k = UpdateParam(ref kp, -DN_GR);
190:
191: if (input != 0)
192: {
193: // encode the nonzero value using Unary Encoding
194:
195: int mag = Math.Abs(input); // absolute value of input coefficient
196: int sign = (input < 0 ? 1 : 0); // sign of input coefficient
197: int maxM = (1 << bitLen) - 1;
198:
199: OutputBit(1, sign); // output the sign bit
200:
201: //a sequence of "magnitude - 1" zeros is written.
202: OutputBit(mag - 1, 0);
203:
204: if (mag < maxM)
205: {
206: OutputBit(1, 1);
207: }
208: }
209: }
210: }
211: }
212:
213: }
214: }