1: //------------------------------------------------------------------------------
2: // Copyright (c) Microsoft Corporation. All rights reserved.
3: //------------------------------------------------------------------------------
4:
5: using System;
6: using System.Collections.Generic;
7: using Microsoft.Protocols.TestTools.StackSdk.RemoteDesktop.Rdprfx;
8: using System.Drawing;
9: using System.Collections;
10:
11: namespace Microsoft.Protocols.TestTools.StackSdk.RemoteDesktop.Rdpegfx
12: {
13: /// <summary>
14: /// The RemoteFX Progressive encoder
15: /// </summary>
16: public class RfxProgressiveEncoder
17: {
18: const int TileSize = 64;
19:
20: /// <summary>
21: /// Encode a Tile
22: /// </summary>
23: /// <param name="encodingContext">The tile encoding context</param>
24: /// <param name="enTileInfo">The tile to be encoded</param>
25: /// <returns>A array of CompressedTile which contains the encoded tiles</returns>
26: public static EncodedTile[] EncodeTile(RfxProgressiveCodecContext encodingContext, TileState enTileInfo)
27: {
28: EncodedTileType targetType = encodingContext.UseProgressive ? EncodedTileType.FirstPass : EncodedTileType.Simple;
29:
30: //File RGB
31: FillRgbData(encodingContext, enTileInfo.GetRgb());
32:
33: //Do color conversion
34: RemoteFXEncoder.RGBToYCbCr(encodingContext);
35:
36: //Do DWT
37: if (encodingContext.UseReduceExtrapolate)
38: {
39: //Do DWT using UseReduce Extrapolate method
40: DWT(encodingContext);
41: }
42: else
43: {
44: RemoteFXEncoder.DWT(encodingContext);
45: }
46:
47: //Do quantiztion
48: Quantization(encodingContext);
49:
50: //Do linearization (LL3 delta not computed)
51: Linearization_NoLL3Delta(encodingContext);
52:
53: //Update new DWT to tile
54: DwtTile dwt = new DwtTile(
55: (short[])encodingContext.YComponent.Clone(),
56: (short[])encodingContext.CbComponent.Clone(),
57: (short[])encodingContext.CrComponent.Clone(),
58: encodingContext.CodecQuantVals,
59: encodingContext.QuantIdxY,
60: encodingContext.QuantIdxCb,
61: encodingContext.QuantIdxCr,
62: encodingContext.UseReduceExtrapolate
63: );
64: enTileInfo.UpdateDwt(dwt);
65:
66:
67: //Sub-Band Diffing
68: if (encodingContext.UseDifferenceTile)
69: {
70: SubBandDiffing_DT(encodingContext, enTileInfo);
71: }
72:
73: if (targetType == EncodedTileType.Simple)
74: {
75: ComputeLL3Deltas(encodingContext);
76:
77: RemoteFXEncoder.RLGREncode(encodingContext);
78: EncodedTile cpTile = new EncodedTile();
79: cpTile.YEncodedData = (byte[])encodingContext.YData.Clone();
80: cpTile.CbEncodedData = (byte[])encodingContext.CbData.Clone();
81: cpTile.CrEncodedData = (byte[])encodingContext.CrData.Clone();
82: cpTile.DataType = EncodedTileType.Simple;
83: cpTile.IsDifferenceTile = encodingContext.UseDifferenceTile;
84: cpTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
85: cpTile.CodecQuantVals = encodingContext.CodecQuantVals;
86: cpTile.QuantIdxY = encodingContext.QuantIdxY;
87: cpTile.QuantIdxCb = encodingContext.QuantIdxCb;
88: cpTile.QuantIdxCr = encodingContext.QuantIdxCr;
89: cpTile.ProgCodecQuant = null;
90: return new EncodedTile[] { cpTile };
91: }
92: else
93: {
94: List<EncodedTile> progCTileList = new List<EncodedTile>();
95: //Init DRS, DAS
96: encodingContext.DRS = new DwtTile(encodingContext.YComponent, encodingContext.CbComponent, encodingContext.CrComponent);
97: encodingContext.DAS = new DwtTile(new short[RdpegfxTileUtils.ComponentElementCount], new short[RdpegfxTileUtils.ComponentElementCount], new short[RdpegfxTileUtils.ComponentElementCount]);
98:
99: #region Chunk 25, first pass
100:
101: ProgressiveQuantization(encodingContext, ProgressiveChunk_Values.kChunk_25);
102:
103: //Compute ProgQ LL3 deltas
104: encodingContext.YComponent = encodingContext.ProgQ.Y_DwtQ;
105: encodingContext.CbComponent = encodingContext.ProgQ.Cb_DwtQ;
106: encodingContext.CrComponent = encodingContext.ProgQ.Cr_DwtQ;
107:
108: ComputeLL3Deltas(encodingContext);
109:
110: RemoteFXEncoder.RLGREncode(encodingContext);
111: EncodedTile firstPassTile = new EncodedTile();
112: firstPassTile.YEncodedData = (byte[])encodingContext.YData.Clone();
113: firstPassTile.CbEncodedData = (byte[])encodingContext.CbData.Clone();
114: firstPassTile.CrEncodedData = (byte[])encodingContext.CrData.Clone();
115: firstPassTile.DataType = EncodedTileType.FirstPass;
116: firstPassTile.IsDifferenceTile = encodingContext.UseDifferenceTile;
117: firstPassTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
118: firstPassTile.CodecQuantVals = encodingContext.CodecQuantVals;
119: firstPassTile.QuantIdxY = encodingContext.QuantIdxY;
120: firstPassTile.QuantIdxCb = encodingContext.QuantIdxCb;
121: firstPassTile.QuantIdxCr = encodingContext.QuantIdxCr;
122: firstPassTile.ProgCodecQuant = RdpegfxTileUtils.GetProgCodecQuant(ProgressiveChunk_Values.kChunk_25);
123: progCTileList.Add(firstPassTile);
124: encodingContext.prevProgQuant = RdpegfxTileUtils.GetProgCodecQuant(ProgressiveChunk_Values.kChunk_25);
125:
126: //Update DRS
127: encodingContext.DRS.Sub(encodingContext.DTS);
128: //Update DAS
129: encodingContext.DAS.Add(encodingContext.DTS);
130: #endregion
131:
132: #region Chunk 50,75,100, upgrade pass
133: ProgressiveChunk_Values[] upgradeChunks = { ProgressiveChunk_Values.kChunk_50, ProgressiveChunk_Values.kChunk_75, ProgressiveChunk_Values.kChunk_100 };
134:
135: foreach (ProgressiveChunk_Values tChunk in upgradeChunks)
136: {
137: ProgressiveQuantization(encodingContext, tChunk);
138:
139: RFX_PROGRESSIVE_CODEC_QUANT progquant = RdpegfxTileUtils.GetProgCodecQuant(tChunk);
140:
141: progCTileList.Add(SRLEncode(encodingContext, progquant));
142:
143: //Update DRS
144: encodingContext.DRS.Sub(encodingContext.DTS);
145: //Update DAS
146: encodingContext.DAS.Add(encodingContext.DTS);
147:
148: encodingContext.prevProgQuant = progquant;
149: }
150:
151: return progCTileList.ToArray();
152:
153: #endregion
154:
155: }
156: }
157:
158: #region File RGB Data
159:
160: static void FillRgbData(RfxProgressiveCodecContext encodingContext, RgbTile rgbTile)
161: {
162: encodingContext.RSet = rgbTile.RSet;
163: encodingContext.GSet = rgbTile.GSet;
164: encodingContext.BSet = rgbTile.BSet;
165: }
166:
167: #endregion
168:
169: #region DWT
170:
171: //DWT
172: internal static void DWT(RfxProgressiveCodecContext encodingContext)
173: {
174: DWT_Component(encodingContext.YSet);
175: DWT_Component(encodingContext.CbSet);
176: DWT_Component(encodingContext.CrSet);
177: }
178:
179: private static short DWT_H(short[] dataArr, int n)
180: {
181: //n < dataArr.length/2
182: short x2n, x2n1, x2n2;
183: int maxIdx = dataArr.Length - 1;
184: if (n == -1)
185: {
186: x2n = dataArr[2];
187: x2n1 = dataArr[1];
188: x2n2 = dataArr[0];
189: }
190: else
191: {
192: x2n = dataArr[2 * n];
193:
194: if (2 * n + 1 > maxIdx)
195: {
196: x2n1 = dataArr[2 * maxIdx - (2 * n + 1)];
197: }
198: else
199: {
200: x2n1 = dataArr[2 * n + 1];
201: }
202:
203: if (2 * n + 2 >= maxIdx)
204: {
205: x2n2 = dataArr[2 * maxIdx - (2 * n + 2)];
206: }
207: else
208: {
209: x2n2 = dataArr[2 * n + 2];
210: }
211: }
212:
213: //short result = (short)((x2n1 - (x2n + x2n2 + 0.0f) / 2) / 2);
214: short result = (short)((x2n1 - (((x2n + x2n2) >> 1))) >> 1);
215: return result;
216: }
217:
218: private static short DWT_L(short[] dataArr, int n)
219: {
220: //short result = (short)(dataArr[2 * n] + (DWT_H(dataArr, n - 1) + DWT_H(dataArr, n)) / 2);
221: short result = (short)(dataArr[2 * n] + ((DWT_H(dataArr, n - 1) + DWT_H(dataArr, n)) >> 1));
222: return result;
223: }
224:
225: public static void DWT(short[] dataArr)
226: {
227: int N = dataArr.Length / 2;
228: int hLen, lLen;
229: short[] data2Dwt;
230: lLen = dataArr.Length / 2 + 1;
231: hLen = dataArr.Length - lLen;
232:
233: short[] hResult = new short[hLen];
234: short[] lResult = new short[lLen];
235:
236: if (dataArr.Length == TileSize)
237: {
238: //First pass
239: data2Dwt = new short[TileSize + 1];
240: Array.Copy(dataArr, data2Dwt, TileSize);
241: data2Dwt[TileSize] = (short)(2 * data2Dwt[TileSize - 1] - data2Dwt[TileSize - 2]);
242: }
243: else
244: {
245: //Second and Third pass
246: data2Dwt = dataArr;
247: }
248:
249: for (int i = 0; i < hLen; i++)
250: {
251: hResult[i] = DWT_H(data2Dwt, i);
252: }
253:
254: for (int i = 0; i < lLen; i++)
255: {
256: lResult[i] = DWT_L(data2Dwt, i);
257: }
258:
259: for (int i = 0; i < lLen; i++)
260: {
261: dataArr[i] = lResult[i];
262: }
263:
264: for (int i = 0; i < hLen; i++)
265: {
266: dataArr[lLen + i] = hResult[i];
267: }
268: }
269:
270: private static void DWT_Pass(short[,] data2D, int pass)
271: {
272: //level > 0
273: //data2D.Length % (1<<(level - 1)) == 0
274: //int inScopelen = TileSize >> (level - 1);
275: int inScopelen;
276: switch (pass)
277: {
278: case 1:
279: {
280: // First pass
281: inScopelen = 64;
282: break;
283: }
284: case 2:
285: {
286: // Second pass
287: inScopelen = 33;
288: break;
289: }
290: case 3:
291: {
292: // Third pass
293: inScopelen = 17;
294: break;
295: }
296: default:
297: {
298: throw new InvalidOperationException("DWT_2D: the parameter level should only be 1, 2, or 3.");
299: }
300: }
301:
302: //Vertical DWT
303: for (int x = 0; x < inScopelen; x++)
304: {
305: short[] col;
306: RemoteFXEncoder.getColFrom2DArr<short>(data2D, out col, x, inScopelen);
307: DWT(col);
308: for (int y = 0; y < inScopelen; y++)
309: {
310: data2D[x, y] = col[y];
311: }
312: }
313: //Horizontal DWT
314: for (int y = 0; y < inScopelen; y++)
315: {
316: short[] row;
317: RemoteFXEncoder.getRowFrom2DArr<short>(data2D, out row, y, inScopelen);
318: DWT(row);
319: for (int x = 0; x < inScopelen; x++)
320: {
321: data2D[x, y] = row[x];
322: }
323: }
324: }
325:
326: protected static void DWT_Component(short[,] component)
327: {
328: DWT_Pass(component, 1);
329: DWT_Pass(component, 2);
330: DWT_Pass(component, 3);
331: }
332:
333: #endregion
334:
335: #region Quantization
336:
337: public static void Quantization(RfxProgressiveCodecContext encodingContext)
338: {
339: doQuantization_Component(encodingContext.YSet, encodingContext.CodecQuantVals[encodingContext.QuantIdxY], encodingContext.UseReduceExtrapolate);
340: doQuantization_Component(encodingContext.CbSet, encodingContext.CodecQuantVals[encodingContext.QuantIdxCb], encodingContext.UseReduceExtrapolate);
341: doQuantization_Component(encodingContext.CrSet, encodingContext.CodecQuantVals[encodingContext.QuantIdxCr], encodingContext.UseReduceExtrapolate);
342: }
343:
344: protected static void doQuantization_Component(short[,] component, TS_RFX_CODEC_QUANT tsRfxCodecQuant, bool useReduceExtrapolate)
345: {
346: // Quantization factor: HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, LL3
347: Hashtable scaleValueTable = new Hashtable();
348: int HL1_Factor = tsRfxCodecQuant.HL1_HH1 & 0x0f;
349: int LH1_Factor = (tsRfxCodecQuant.HH2_LH1 & 0xf0) >> 4;
350: int HH1_Factor = (tsRfxCodecQuant.HL1_HH1 & 0xf0) >> 4;
351: int HL2_Factor = (tsRfxCodecQuant.LH2_HL2 & 0xf0) >> 4;
352: int LH2_Factor = tsRfxCodecQuant.LH2_HL2 & 0x0f;
353: int HH2_Factor = tsRfxCodecQuant.HH2_LH1 & 0x0f;
354: int HL3_Factor = tsRfxCodecQuant.HL3_HH3 & 0x0f;
355: int LH3_Factor = (tsRfxCodecQuant.LL3_LH3 & 0xf0) >> 4;
356: int HH3_Factor = (tsRfxCodecQuant.HL3_HH3 & 0xf0) >> 4;
357: int LL3_Factor = tsRfxCodecQuant.LL3_LH3 & 0x0f;
358:
359: BandType_Values[] bandArr = new BandType_Values[] { BandType_Values.HL1, BandType_Values.LH1, BandType_Values.HH1, BandType_Values.HL2, BandType_Values.LH2, BandType_Values.HH2, BandType_Values.HL3, BandType_Values.LH3, BandType_Values.HH3, BandType_Values.LL3 };
360: int[] bandFactor = new int[] { HL1_Factor, LH1_Factor, HH1_Factor, HL2_Factor, LH2_Factor, HH2_Factor, HL3_Factor, LH3_Factor, HH3_Factor, LL3_Factor };
361:
362: for (int i = 0; i < bandArr.Length; i++)
363: {
364: BandRect br = RdpegfxTileUtils.GetBandRect(bandArr[i], useReduceExtrapolate);
365: doQuantization_Subband(component, br.left, br.top, br.right, br.bottom, bandFactor[i]);
366: }
367: }
368:
369: private static void doQuantization_Subband(short[,] input, int left, int top, int right, int bottom, int factor)
370: {
371: for (int x = left; x <= right; x++)
372: {
373: for (int y = top; y <= bottom; y++)
374: {
375: input[x, y] = quant(input[x, y], factor);
376: }
377: }
378: }
379:
380: private static short quant(short input, int factor)
381: {
382: short output;
383: output = (short)(Math.Abs(input) >> (factor - 6));
384: if (input < 0) output *= -1;
385: return output;
386: }
387: #endregion
388:
389: #region Linearization
390:
391: public static void Linearization_NoLL3Delta(RfxProgressiveCodecContext encodingContext)
392: {
393: linearization_Compontent(encodingContext.YSet, encodingContext.UseReduceExtrapolate, out encodingContext.YComponent);
394: linearization_Compontent(encodingContext.CbSet, encodingContext.UseReduceExtrapolate, out encodingContext.CbComponent);
395: linearization_Compontent(encodingContext.CrSet, encodingContext.UseReduceExtrapolate, out encodingContext.CrComponent);
396: }
397:
398: public static void ComputeLL3Deltas(RfxProgressiveCodecContext encodingContext)
399: {
400: int ll3Len = RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, encodingContext.UseReduceExtrapolate);
401: int ll3Idx = RdpegfxTileUtils.ComponentElementCount - ll3Len;
402:
403: //for (int i = ll3Idx + 1; i < TileUtils.ComponentElementCount; i++)
404: for (int i = RdpegfxTileUtils.ComponentElementCount - 1; i >= ll3Idx + 1; i--)
405: {
406: encodingContext.YComponent[i] = (short)(encodingContext.YComponent[i] - encodingContext.YComponent[i - 1]);
407: encodingContext.CbComponent[i] = (short)(encodingContext.CbComponent[i] - encodingContext.CbComponent[i - 1]);
408: encodingContext.CrComponent[i] = (short)(encodingContext.CrComponent[i] - encodingContext.CrComponent[i - 1]);
409: }
410:
411: }
412:
413: protected static void linearization_Compontent(short[,] compontent, bool useReduceExtrapolate, out short[] lineOutput)
414: {
415: //sequence: HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, and LL3
416: lineOutput = new short[TileSize * TileSize];
417: int curIdx = 0;
418:
419: BandType_Values[] bandArr = new BandType_Values[] { BandType_Values.HL1, BandType_Values.LH1, BandType_Values.HH1, BandType_Values.HL2, BandType_Values.LH2, BandType_Values.HH2, BandType_Values.HL3, BandType_Values.LH3, BandType_Values.HH3, BandType_Values.LL3 };
420: short[] bandOutput;
421: BandRect curBand;
422:
423: for (int i = 0; i < bandArr.Length; i++)
424: {
425: curBand = RdpegfxTileUtils.GetBandRect(bandArr[i], useReduceExtrapolate);
426: linearization_SubBand(compontent, curBand.left, curBand.top, curBand.right, curBand.bottom, out bandOutput);
427: Array.Copy(bandOutput, 0, lineOutput, curIdx, bandOutput.Length);
428: curIdx += bandOutput.Length;
429: }
430:
431: }
432:
433: private static void linearization_SubBand(short[,] input, int left, int top, int right, int bottom, out short[] bandOutput)
434: {
435: int totalNum = (right - left + 1) * (bottom - top + 1);
436: bandOutput = new short[totalNum];
437: int curIdx = 0;
438: for (int y = top; y <= bottom; y++)
439: {
440: for (int x = left; x <= right; x++)
441: {
442: bandOutput[curIdx++] = input[x, y];
443: }
444: }
445: }
446:
447:
448:
449: #endregion
450:
451: #region SRL Encoder
452:
453: //SRLEncode
454: public static EncodedTile SRLEncode(RfxProgressiveCodecContext encodingContext, Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT progQuant)
455: {
456: SRLEncoder encoder = new SRLEncoder();
457:
458: List<short> yDataToSrl = new List<short>();
459: List<short> cbDataToSrl = new List<short>();
460: List<short> crDataToSrl = new List<short>();
461:
462: List<int> yDataToSrlBitLen = new List<int>();
463: List<int> cbDataToSrlBitLen = new List<int>();
464: List<int> crDataToSrlBitLen = new List<int>();
465:
466: BitStream yRawBitStream = new BitStream();
467: BitStream cbRawBitStream = new BitStream();
468: BitStream crRawBitStream = new BitStream();
469:
470: int nonLL3Len = RdpegfxTileUtils.ComponentElementCount - RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, encodingContext.UseReduceExtrapolate);
471: Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT prevProgQuant = encodingContext.prevProgQuant;
472: Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT curProgQuant = progQuant;
473:
474: for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
475: {
476: BandType_Values band = RdpegfxTileUtils.GetBandByIndex(i, encodingContext.UseReduceExtrapolate);
477:
478: int targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.yQuantValues, band);
479: int prevBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prevProgQuant.yQuantValues, band);
480: int bitCount = prevBitPos - targetBitPos;
481: if (bitCount > 0)
482: {
483: if (encodingContext.DAS.Y_DwtQ[i] == 0 && i < nonLL3Len)
484: {
485: yDataToSrl.Add(encodingContext.ProgQ.Y_DwtQ[i]);
486: yDataToSrlBitLen.Add(bitCount);
487: }
488: else
489: {
490: //Add raw data
491: yRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Y_DwtQ[i]));
492: }
493: }
494:
495: targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.cbQuantValues, band);
496: prevBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prevProgQuant.cbQuantValues, band);
497: bitCount = prevBitPos - targetBitPos;
498: if (bitCount > 0)
499: {
500: if (encodingContext.DAS.Cb_DwtQ[i] == 0 && i < nonLL3Len)
501: {
502: cbDataToSrl.Add(encodingContext.ProgQ.Cb_DwtQ[i]);
503: cbDataToSrlBitLen.Add(bitCount);
504: }
505: else
506: {
507: //Add raw data
508: cbRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Cb_DwtQ[i]));
509: }
510: }
511:
512: targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.crQuantValues, band);
513: prevBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.crQuantValues, band);
514: bitCount = prevBitPos - targetBitPos;
515: if (bitCount > 0)
516: {
517: if (encodingContext.DAS.Cr_DwtQ[i] == 0 && i < nonLL3Len)
518: {
519: crDataToSrl.Add(encodingContext.ProgQ.Cr_DwtQ[i]);
520: crDataToSrlBitLen.Add(bitCount);
521: }
522: else
523: {
524: //Add raw data
525: crRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Cr_DwtQ[i]));
526: }
527: }
528: }
529:
530: encodingContext.YData = encoder.Encode(yDataToSrl.ToArray(), yDataToSrlBitLen.ToArray());
531: encodingContext.CbData = encoder.Encode(cbDataToSrl.ToArray(), cbDataToSrlBitLen.ToArray());
532: encodingContext.CrData = encoder.Encode(crDataToSrl.ToArray(), crDataToSrlBitLen.ToArray());
533:
534: EncodedTile ugTile = new EncodedTile();
535: ugTile.YEncodedData = (byte[])encodingContext.YData.Clone();
536: ugTile.CbEncodedData = (byte[])encodingContext.CbData.Clone();
537: ugTile.CrEncodedData = (byte[])encodingContext.CrData.Clone();
538: ugTile.YRawData = yRawBitStream.ToBytes();
539: ugTile.CbRawData = cbRawBitStream.ToBytes();
540: ugTile.CrRawData = crRawBitStream.ToBytes();
541: ugTile.DataType = EncodedTileType.UpgradePass;
542: ugTile.IsDifferenceTile = encodingContext.UseDifferenceTile;
543: ugTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
544: ugTile.CodecQuantVals = encodingContext.CodecQuantVals;
545: ugTile.QuantIdxY = encodingContext.QuantIdxY;
546: ugTile.QuantIdxCb = encodingContext.QuantIdxCb;
547: ugTile.QuantIdxCr = encodingContext.QuantIdxCr;
548: ugTile.ProgCodecQuant = curProgQuant;
549:
550: return ugTile;
551:
552: }
553:
554: #endregion
555:
556: #region Sub-Band Diffing
557: //Compute the difference tile dwt
558: public static void SubBandDiffing_DT(RfxProgressiveCodecContext encodingContext, TileState enTileInfo)
559: {
560: if (encodingContext.UseDifferenceTile)
561: {
562: DwtTile oldDwt = enTileInfo.GetOldDwt();
563: if (oldDwt != null)
564: {
565: short[] yDiffDwt, cbDiffDwt, crDiffDwt;
566: int lenOfNonLL3Band = (RdpegfxTileUtils.ComponentElementCount - RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, encodingContext.UseReduceExtrapolate));// ? 81 : 64;
567: int yNewZeroCount, cbNewZeroCount, crNewZeroCount;
568: int yDiffZeroCount, cbDiffZeroCount, crDiffZeroCount;
569: yDiffDwt = RdpegfxTileUtils.SubDiffingDwt(encodingContext.YComponent, oldDwt.Y_DwtQ, lenOfNonLL3Band, out yNewZeroCount, out yDiffZeroCount);
570: cbDiffDwt = RdpegfxTileUtils.SubDiffingDwt(encodingContext.CbComponent, oldDwt.Cb_DwtQ, lenOfNonLL3Band, out cbNewZeroCount, out cbDiffZeroCount);
571: crDiffDwt = RdpegfxTileUtils.SubDiffingDwt(encodingContext.CrComponent, oldDwt.Cr_DwtQ, lenOfNonLL3Band, out crNewZeroCount, out crDiffZeroCount);
572: if ((yDiffDwt != null && cbDiffDwt != null && crDiffDwt != null) &&
573: (yNewZeroCount + cbNewZeroCount + crNewZeroCount < yDiffZeroCount + cbDiffZeroCount + crDiffZeroCount))
574: {//use difference tile
575: encodingContext.YComponent = yDiffDwt;
576: encodingContext.CbComponent = cbDiffDwt;
577: encodingContext.CrComponent = crDiffDwt;
578: return;
579: }
580: }
581: }
582: encodingContext.UseDifferenceTile = false;//use orginal tile
583: }
584:
585: #endregion
586:
587: #region Extra(Progressive) Quantization
588:
589: public static void ProgressiveQuantization(RfxProgressiveCodecContext encodingContext, ProgressiveChunk_Values chunk)
590: {
591: DwtBands yBD = DwtBands.GetFromLinearizationResult(encodingContext.DRS.Y_DwtQ, encodingContext.UseReduceExtrapolate);
592: DwtBands cbBD = DwtBands.GetFromLinearizationResult(encodingContext.DRS.Cb_DwtQ, encodingContext.UseReduceExtrapolate);
593: DwtBands crBD = DwtBands.GetFromLinearizationResult(encodingContext.DRS.Cr_DwtQ, encodingContext.UseReduceExtrapolate);
594:
595: ProgressiveQuantization_Component(yBD, TileComponents.Y, chunk);
596: ProgressiveQuantization_Component(cbBD, TileComponents.Cb, chunk);
597: ProgressiveQuantization_Component(crBD, TileComponents.Cr, chunk);
598:
599: DwtTile dwtDts = new DwtTile(yBD.GetLinearizationData(), cbBD.GetLinearizationData(), crBD.GetLinearizationData());
600: encodingContext.ProgQ = dwtDts;
601:
602: //Compute DTS
603: encodingContext.DTS = GetDTS(encodingContext, chunk);
604: }
605:
606: protected static void ProgressiveQuantization_Component(DwtBands dwt, TileComponents component, ProgressiveChunk_Values chunk)
607: {
608: //HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, and LL3
609: ProgressiveQuantization_Band(dwt.HL1, BandType_Values.HL1, component, chunk);
610: ProgressiveQuantization_Band(dwt.LH1, BandType_Values.LH1, component, chunk);
611: ProgressiveQuantization_Band(dwt.HH1, BandType_Values.HH1, component, chunk);
612: ProgressiveQuantization_Band(dwt.HL2, BandType_Values.HL2, component, chunk);
613: ProgressiveQuantization_Band(dwt.LH2, BandType_Values.LH2, component, chunk);
614: ProgressiveQuantization_Band(dwt.HH2, BandType_Values.HH2, component, chunk);
615: ProgressiveQuantization_Band(dwt.HL3, BandType_Values.HL3, component, chunk);
616: ProgressiveQuantization_Band(dwt.LH3, BandType_Values.LH3, component, chunk);
617: ProgressiveQuantization_Band(dwt.HH3, BandType_Values.HH3, component, chunk);
618: ProgressiveQuantization_Band(dwt.LL3, BandType_Values.LL3, component, chunk);
619:
620: }
621:
622: protected static void ProgressiveQuantization_Component(DwtBands dwt, TileComponents component, RFX_PROGRESSIVE_CODEC_QUANT quants)
623: {
624: //HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, and LL3
625: ProgressiveQuantization_Band(dwt.HL1, BandType_Values.HL1, component, quants);
626: ProgressiveQuantization_Band(dwt.LH1, BandType_Values.LH1, component, quants);
627: ProgressiveQuantization_Band(dwt.HH1, BandType_Values.HH1, component, quants);
628: ProgressiveQuantization_Band(dwt.HL2, BandType_Values.HL2, component, quants);
629: ProgressiveQuantization_Band(dwt.LH2, BandType_Values.LH2, component, quants);
630: ProgressiveQuantization_Band(dwt.HH2, BandType_Values.HH2, component, quants);
631: ProgressiveQuantization_Band(dwt.HL3, BandType_Values.HL3, component, quants);
632: ProgressiveQuantization_Band(dwt.LH3, BandType_Values.LH3, component, quants);
633: ProgressiveQuantization_Band(dwt.HH3, BandType_Values.HH3, component, quants);
634: ProgressiveQuantization_Band(dwt.LL3, BandType_Values.LL3, component, quants);
635: }
636:
637: static void ProgressiveQuantization_Band(short[] bandData, BandType_Values band, TileComponents component, ProgressiveChunk_Values chunk)
638: {
639: int bitPos = RdpegfxTileUtils.GetBitPosForChunk(chunk, component, band);
640: for (int i = 0; i < bandData.Length; i++)
641: {
642: bandData[i] = FunProgQ(bandData[i], bitPos, band);
643: }
644:
645: }
646:
647: static void ProgressiveQuantization_Band(short[] bandData, BandType_Values band, TileComponents component, RFX_PROGRESSIVE_CODEC_QUANT quants)
648: {
649: int bitPos = RdpegfxTileUtils.GetBitPosForQuant(quants, component, band);
650: for (int i = 0; i < bandData.Length; i++)
651: {
652: bandData[i] = FunProgQ(bandData[i], bitPos, band);
653: }
654: }
655:
656: static short FunProgQ(short v, int bitPos, BandType_Values band)
657: {
658: if (band != BandType_Values.LL3)
659: {
660: if (v >= 0) return (short)(v >> bitPos);
661: return (short)-((-v) >> bitPos);
662: }
663: else
664: {
665: return (short)(v >> bitPos);
666: }
667: }
668:
669: static DwtTile GetDTS(RfxProgressiveCodecContext encodingContext, ProgressiveChunk_Values chunk)
670: {
671: DwtBands yBD = DwtBands.GetFromLinearizationResult(encodingContext.DRS.Y_DwtQ, encodingContext.UseReduceExtrapolate);
672: DwtBands cbBD = DwtBands.GetFromLinearizationResult(encodingContext.DRS.Cb_DwtQ, encodingContext.UseReduceExtrapolate);
673: DwtBands crBD = DwtBands.GetFromLinearizationResult(encodingContext.DRS.Cr_DwtQ, encodingContext.UseReduceExtrapolate);
674:
675: DTS_Component(yBD, TileComponents.Y, chunk);
676: DTS_Component(cbBD, TileComponents.Cb, chunk);
677: DTS_Component(crBD, TileComponents.Cr, chunk);
678:
679: DwtTile dwtDts = new DwtTile(yBD.GetLinearizationData(), cbBD.GetLinearizationData(), crBD.GetLinearizationData());
680: return dwtDts;
681: }
682:
683: protected static void DTS_Component(DwtBands dwt, TileComponents component, ProgressiveChunk_Values chunk)
684: {
685: //HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, and LL3
686: DTS_Band(dwt.HL1, BandType_Values.HL1, component, chunk);
687: DTS_Band(dwt.LH1, BandType_Values.LH1, component, chunk);
688: DTS_Band(dwt.HH1, BandType_Values.HH1, component, chunk);
689: DTS_Band(dwt.HL2, BandType_Values.HL2, component, chunk);
690: DTS_Band(dwt.LH2, BandType_Values.LH2, component, chunk);
691: DTS_Band(dwt.HH2, BandType_Values.HH2, component, chunk);
692: DTS_Band(dwt.HL3, BandType_Values.HL3, component, chunk);
693: DTS_Band(dwt.LH3, BandType_Values.LH3, component, chunk);
694: DTS_Band(dwt.HH3, BandType_Values.HH3, component, chunk);
695: DTS_Band(dwt.LL3, BandType_Values.LL3, component, chunk);
696:
697: }
698:
699: protected static void DTS_Component(DwtBands dwt, TileComponents component, RFX_PROGRESSIVE_CODEC_QUANT quants)
700: {
701: //HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, and LL3
702: DTS_Band(dwt.HL1, BandType_Values.HL1, component, quants);
703: DTS_Band(dwt.LH1, BandType_Values.LH1, component, quants);
704: DTS_Band(dwt.HH1, BandType_Values.HH1, component, quants);
705: DTS_Band(dwt.HL2, BandType_Values.HL2, component, quants);
706: DTS_Band(dwt.LH2, BandType_Values.LH2, component, quants);
707: DTS_Band(dwt.HH2, BandType_Values.HH2, component, quants);
708: DTS_Band(dwt.HL3, BandType_Values.HL3, component, quants);
709: DTS_Band(dwt.LH3, BandType_Values.LH3, component, quants);
710: DTS_Band(dwt.HH3, BandType_Values.HH3, component, quants);
711: DTS_Band(dwt.LL3, BandType_Values.LL3, component, quants);
712:
713: }
714:
715: static void DTS_Band(short[] bandData, BandType_Values band, TileComponents component, ProgressiveChunk_Values chunk)
716: {
717: int bitPos = RdpegfxTileUtils.GetBitPosForChunk(chunk, component, band);
718: for (int i = 0; i < bandData.Length; i++)
719: {
720: bandData[i] = FunDTS(bandData[i], bitPos, band);
721: }
722:
723: }
724:
725: static void DTS_Band(short[] bandData, BandType_Values band, TileComponents component, RFX_PROGRESSIVE_CODEC_QUANT quants)
726: {
727: int bitPos = RdpegfxTileUtils.GetBitPosForQuant(quants, component, band);
728: for (int i = 0; i < bandData.Length; i++)
729: {
730: bandData[i] = FunDTS(bandData[i], bitPos, band);
731: }
732:
733: }
734:
735: static short FunDTS(short v, int bitPos, BandType_Values band)
736: {
737: if (band != BandType_Values.LL3)
738: {
739: if (v >= 0) return (short)((v >> bitPos) << bitPos);
740: return (short)-(((-v) >> bitPos) << bitPos);
741: }
742: else
743: {
744: return (short)(v >> bitPos << bitPos);
745: }
746: }
747:
748: #endregion
749:
750: static void SetTriState(DwtTile inputTile, bool useReduceExtrapolate)
751: {
752: int ll3Len = RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, useReduceExtrapolate);
753: int ll3Idx = RdpegfxTileUtils.ComponentElementCount - ll3Len;
754:
755: DwtTile stateTile = new DwtTile(
756: new short[RdpegfxTileUtils.ComponentElementCount], //y state
757: new short[RdpegfxTileUtils.ComponentElementCount], //cb state
758: new short[RdpegfxTileUtils.ComponentElementCount]); //cr state
759:
760: for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
761: {
762: if (i < ll3Idx)
763: {
764: if (inputTile.Y_DwtQ[i] == 0)
765: {
766: stateTile.Y_DwtQ[i] = 0;
767: }
768: else if (inputTile.Y_DwtQ[i] > 0)
769: {
770: stateTile.Y_DwtQ[i] = 1;
771: } if (inputTile.Y_DwtQ[i] < 0)
772: {
773: stateTile.Y_DwtQ[i] = -1;
774: }
775:
776: if (inputTile.Cb_DwtQ[i] == 0)
777: {
778: stateTile.Cb_DwtQ[i] = 0;
779: }
780: else if (inputTile.Cb_DwtQ[i] > 0)
781: {
782: stateTile.Cb_DwtQ[i] = 1;
783: } if (inputTile.Cb_DwtQ[i] < 0)
784: {
785: stateTile.Cb_DwtQ[i] = -1;
786: }
787:
788: if (inputTile.Cr_DwtQ[i] == 0)
789: {
790: stateTile.Cr_DwtQ[i] = 0;
791: }
792: else if (inputTile.Cr_DwtQ[i] > 0)
793: {
794: stateTile.Cr_DwtQ[i] = 1;
795: } if (inputTile.Cr_DwtQ[i] < 0)
796: {
797: stateTile.Cr_DwtQ[i] = -1;
798: }
799: }
800: else
801: {
802: stateTile.Y_DwtQ[i] = 1;
803: stateTile.Cb_DwtQ[i] = 1;
804: stateTile.Cr_DwtQ[i] = 1;
805: }
806: }
807: }
808: }
809: }