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.Collections;
   9:   
  10:  namespace Microsoft.Protocols.TestTools.StackSdk.RemoteDesktop.Rdpegfx
  11:  {
  12:      /// <summary>
  13:      /// The RemoteFX Progressive Decoder
  14:      /// </summary>
  15:      public class RfxProgressiveDecoder
  16:      {
  17:          /// <summary>
  18:          /// Decode a encoded tile
  19:          /// </summary>
  20:          /// <param name="enTile">Represents a encoded tile.</param>
  21:          /// <param name="tState">The context state of the tile that going to be decoded.</param>
  22:          public static void DecodeTile(EncodedTile enTile, TileState tState)
  23:          {
  24:              RfxProgressiveCodecContext codecContext = new RfxProgressiveCodecContext(
  25:                  enTile.CodecQuantVals,
  26:                  enTile.QuantIdxY, 
  27:                  enTile.QuantIdxCb, 
  28:                  enTile.QuantIdxCr,
  29:                  enTile.DataType == EncodedTileType.Simple ? false : true, 
  30:                  enTile.IsDifferenceTile, 
  31:                  enTile.UseReduceExtrapolate);
  32:   
  33:              //RLGR/SRL Decode
  34:              if (enTile.DataType == EncodedTileType.FirstPass || enTile.DataType == EncodedTileType.Simple)
  35:              {   //first pass or simple
  36:                  codecContext.YData = enTile.YEncodedData;
  37:                  codecContext.CbData = enTile.CbEncodedData;
  38:                  codecContext.CrData = enTile.CrEncodedData;
  39:                  RemoteFXDecoder.RLGRDecode(codecContext);
  40:                  ComputeOriginalLL3FromDeltas(codecContext);
  41:              }
  42:              else
  43:              {
  44:                  SRLDecode(codecContext, enTile, tState);
  45:              }
  46:   
  47:              //Progressive Dequantization
  48:              if (enTile.DataType != EncodedTileType.Simple)
  49:              {
  50:                  ProgressiveDeQuantization(codecContext, enTile.ProgCodecQuant);
  51:              }
  52:   
  53:              // Create a DwtTile instance for tri-state
  54:              DwtTile triStateDwt = new DwtTile(codecContext.YComponent, codecContext.CbComponent, codecContext.CrComponent, 
  55:                  enTile.CodecQuantVals, enTile.QuantIdxY, enTile.QuantIdxCb, enTile.QuantIdxCr, enTile.UseReduceExtrapolate, enTile.ProgCodecQuant);
  56:                  
  57:              //Set Tri-State for progressive codec
  58:              if (enTile.DataType == EncodedTileType.FirstPass)
  59:              {
  60:                  //DwtTile tileTriStat = SetTriState(diffDwt, enTile.UseReduceExtrapolate);
  61:                  tState.UpdateTriState(triStateDwt);
  62:              }
  63:              else if (enTile.DataType == EncodedTileType.UpgradePass)
  64:              {
  65:                  DwtTile prvStat = tState.GetTriState();
  66:                  prvStat.Add(triStateDwt);
  67:                  // update ProCodecQuant
  68:                  prvStat.ProgCodecQuant = triStateDwt.ProgCodecQuant;
  69:                  tState.UpdateTriState(prvStat);
  70:              }
  71:   
  72:              // Create another DwtTile instance for DWT Data.
  73:              // The data in diffDwt is the same as triStateDwt, this will makesure the DWT data and tri-state not share the same DWT tile instance
  74:              DwtTile diffDwt = new DwtTile(codecContext.YComponent, codecContext.CbComponent, codecContext.CrComponent, 
  75:                  enTile.CodecQuantVals, enTile.QuantIdxY, enTile.QuantIdxCb, enTile.QuantIdxCr, enTile.UseReduceExtrapolate, enTile.ProgCodecQuant);
  76:   
  77:              //Sum difference
  78:              if ( enTile.IsDifferenceTile || enTile.DataType == EncodedTileType.UpgradePass)
  79:              {
  80:                  tState.AddDwt(diffDwt);
  81:              }
  82:              else
  83:              {
  84:                  tState.UpdateDwt(diffDwt);
  85:              }
  86:          }
  87:   
  88:          /// <summary>
  89:          /// Decode a tile from DWT
  90:          /// </summary>
  91:          /// <param name="codecContext">The codec context which contians the DWT data of a tile.</param>
  92:          public static void DecodeTileFromDwtQ(RfxProgressiveCodecContext codecContext)
  93:          {
  94:              //Sub Band Reconstruction
  95:              SubBandReconstruction(codecContext);
  96:   
  97:              //De-quantization
  98:              Dequantization(codecContext);
  99:   
 100:              //Inverse DWT
 101:              if (codecContext.UseReduceExtrapolate)
 102:              {
 103:                  InverseDWT(codecContext);
 104:              }
 105:              else
 106:              {
 107:                  RemoteFXDecoder.InverseDWT(codecContext);
 108:              }
 109:   
 110:              //(Y, U, V) to (R, G, B)
 111:              RemoteFXDecoder.YCbCrToRGB(codecContext);
 112:          }
 113:   
 114:          #region SRL Decode
 115:   
 116:          public static void SRLDecode(RfxProgressiveCodecContext codecContext, EncodedTile enTile, TileState tState)
 117:          {
 118:              SRLDecoder yDecoder = null;
 119:              SRLDecoder cbDecoder = null;
 120:              SRLDecoder crDecoder = null;
 121:   
 122:              List<short> yData = new List<short>();
 123:              List<short> cbData = new List<short>();
 124:              List<short> crData = new List<short>();
 125:              DwtTile triState = tState.GetTriState();
 126:              RFX_PROGRESSIVE_CODEC_QUANT prvProgQuant = tState.GetDwt().ProgCodecQuant;
 127:              int nonLL3Len = RdpegfxTileUtils.ComponentElementCount - RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, enTile.UseReduceExtrapolate);
 128:   
 129:              if (enTile.YEncodedData != null)
 130:              {
 131:                  yDecoder = new SRLDecoder(enTile.YEncodedData);
 132:              }
 133:   
 134:              if (enTile.CbEncodedData != null)
 135:              {
 136:                  cbDecoder = new SRLDecoder(enTile.CbEncodedData);
 137:              }
 138:   
 139:              if (enTile.CrEncodedData != null)
 140:              {
 141:                  crDecoder = new SRLDecoder(enTile.CrEncodedData);
 142:              }
 143:   
 144:              BitStream yRaw = BitStream.GetFromBytes(enTile.YRawData);
 145:              BitStream cbRaw = BitStream.GetFromBytes(enTile.CbRawData);
 146:              BitStream crRaw = BitStream.GetFromBytes(enTile.CrRawData);
 147:   
 148:              for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
 149:              {
 150:                  BandType_Values band = RdpegfxTileUtils.GetBandByIndex(i, enTile.UseReduceExtrapolate);
 151:   
 152:                  //Y
 153:                  int curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.yQuantValues, band);
 154:                  int prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.yQuantValues, band);
 155:                  int bitCount = prvBitPos - curBitPos;
 156:                  int sign = triState.Y_DwtQ[i];
 157:                  if (bitCount > 0)
 158:                  {
 159:                      if (sign == 0 && i < nonLL3Len)
 160:                      {
 161:                          if (yDecoder != null)
 162:                          {
 163:                              short? decodedValue = yDecoder.DecodeOne(bitCount);
 164:                              if (decodedValue.HasValue)
 165:                              {
 166:                                  yData.Add(decodedValue.Value);
 167:                              }
 168:                              else
 169:                              {
 170:                                  yData.Add(0);
 171:                              }
 172:                          }
 173:                          else
 174:                          {
 175:                              yData.Add(0);
 176:                          }
 177:                      }
 178:                      else
 179:                      {
 180:                          int output;
 181:                          if (yRaw.ReadInt32(bitCount, out output))
 182:                          {
 183:                              if (sign < 0 && i < nonLL3Len) output = -output;
 184:                              yData.Add((short)output);
 185:                          }
 186:                          else
 187:                          {
 188:                              yData.Add(0);
 189:                          }
 190:                      }
 191:                  }
 192:                  else
 193:                  {
 194:                      yData.Add(0);
 195:                  }
 196:   
 197:                  //Cb
 198:                  curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.cbQuantValues, band);
 199:                  prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.cbQuantValues, band);
 200:                  bitCount = prvBitPos - curBitPos;
 201:                  sign = triState.Cb_DwtQ[i];
 202:                  if (bitCount > 0)
 203:                  {
 204:                      if (sign == 0 && i < nonLL3Len)
 205:                      {
 206:                          if (cbDecoder != null)
 207:                          {
 208:                              short? decodedValue = cbDecoder.DecodeOne(bitCount);
 209:                              if (decodedValue.HasValue)
 210:                              {
 211:                                  cbData.Add(decodedValue.Value);
 212:                              }
 213:                              else
 214:                              {
 215:                                  cbData.Add(0);
 216:                              }
 217:                          }
 218:                          else
 219:                          {
 220:                              cbData.Add(0);
 221:                          }
 222:                      }
 223:                      else
 224:                      {
 225:                          int output;
 226:                          if (cbRaw.ReadInt32(bitCount, out output))
 227:                          {
 228:                              if (sign < 0 && i < nonLL3Len) output = -output;
 229:                              cbData.Add((short)output);
 230:                          }
 231:                          else
 232:                          {
 233:                              cbData.Add(0);
 234:                          }
 235:                      }
 236:                  }
 237:                  else
 238:                  {
 239:                      cbData.Add(0);
 240:                  }
 241:   
 242:                  //cr
 243:                  curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.crQuantValues, band);
 244:                  prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.crQuantValues, band);
 245:                  bitCount = prvBitPos - curBitPos;
 246:                  sign = triState.Cr_DwtQ[i];
 247:                  if (bitCount > 0)
 248:                  {
 249:                      if (sign == 0 && i < nonLL3Len)
 250:                      {
 251:                          if (crDecoder != null)
 252:                          {
 253:                              short? decodedValue = crDecoder.DecodeOne(bitCount);
 254:                              if (decodedValue.HasValue)
 255:                              {
 256:                                  crData.Add(decodedValue.Value);
 257:                              }
 258:                              else
 259:                              {
 260:                                  crData.Add(0);
 261:                              }
 262:                          }
 263:                          else
 264:                          {
 265:                              crData.Add(0);
 266:                          }
 267:                      }
 268:                      else
 269:                      {
 270:                          int output;
 271:                          if (crRaw.ReadInt32(bitCount, out output))
 272:                          {
 273:                              if (sign < 0 && i < nonLL3Len) output = -output;
 274:                              crData.Add((short)output);
 275:                          }
 276:                          else
 277:                          {
 278:                              crData.Add(0);
 279:                          }
 280:                      }
 281:                  }
 282:                  else
 283:                  {
 284:                      crData.Add(0);
 285:                  }
 286:              }
 287:   
 288:              codecContext.YComponent = yData.ToArray();
 289:              codecContext.CbComponent = cbData.ToArray();
 290:              codecContext.CrComponent = crData.ToArray();
 291:          }
 292:   
 293:          #endregion
 294:   
 295:          #region Sub-Band Reconstruction
 296:          public static void SubBandReconstruction(RfxProgressiveCodecContext codecContext)
 297:          {
 298:              reconstruction_Component(codecContext.YComponent, out codecContext.YSet, codecContext.UseReduceExtrapolate);
 299:              reconstruction_Component(codecContext.CbComponent, out codecContext.CbSet, codecContext.UseReduceExtrapolate);
 300:              reconstruction_Component(codecContext.CrComponent, out codecContext.CrSet, codecContext.UseReduceExtrapolate);
 301:          }
 302:   
 303:          public static void ComputeOriginalLL3FromDeltas(RfxProgressiveCodecContext codecContext)
 304:          {
 305:              int ll3Len = RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, codecContext.UseReduceExtrapolate);
 306:              int ll3Idx = RdpegfxTileUtils.ComponentElementCount - ll3Len;
 307:   
 308:              for (int i = ll3Idx + 1; i < RdpegfxTileUtils.ComponentElementCount; i++)
 309:              {
 310:                  codecContext.YComponent[i] = (short)(codecContext.YComponent[i] + codecContext.YComponent[i - 1]);
 311:                  codecContext.CbComponent[i] = (short)(codecContext.CbComponent[i] + codecContext.CbComponent[i - 1]);
 312:                  codecContext.CrComponent[i] = (short)(codecContext.CrComponent[i] + codecContext.CrComponent[i - 1]);
 313:              }
 314:   
 315:          }
 316:   
 317:          public static void reconstruction_Component(short[] component1D, out short[,] compontent2D, bool useReduceExtrapolate)
 318:          {
 319:              //sequence: HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, and LL3
 320:              //lineOutput = new short[TileSize * TileSize];
 321:              compontent2D = new short[RdpegfxTileUtils.TileSize, RdpegfxTileUtils.TileSize];
 322:              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 };
 323:   
 324:              int offset = 0;
 325:              BandRect curBand;
 326:   
 327:              for (int i = 0; i < bandArr.Length; i++)
 328:              {
 329:                  curBand = RdpegfxTileUtils.GetBandRect(bandArr[i], useReduceExtrapolate);
 330:                  reconstruction_SubBand(compontent2D, curBand.left, curBand.top, curBand.right, curBand.bottom, component1D, ref offset);
 331:              }
 332:          }
 333:   
 334:          public static void reconstruction_SubBand(short[,] input, int left, int top, int right, int bottom, short[] bandOutput, ref int offset)
 335:          {
 336:              //int totalNum = (right - left + 1) * (bottom - top + 1);
 337:              //bandOutput = new short[totalNum];
 338:              for (int y = top; y <= bottom; y++)
 339:              {
 340:                  for (int x = left; x <= right; x++)
 341:                  {
 342:                      input[x, y] = bandOutput[offset++];
 343:                  }
 344:              }
 345:          }
 346:   
 347:          #endregion
 348:   
 349:          #region Inverse DWT
 350:   
 351:          //InverseDWT
 352:          public static void InverseDWT(RfxProgressiveCodecContext codecContext)
 353:          {
 354:              InverseDWT_Component(codecContext.YSet);
 355:              InverseDWT_Component(codecContext.CbSet);
 356:              InverseDWT_Component(codecContext.CrSet);
 357:          }
 358:   
 359:          protected static void InverseDWT_Component(short[,] component)
 360:          {
 361:              //Level 3, 2, 1
 362:              InverseDWT_2D(component, 3);
 363:              InverseDWT_2D(component, 2);
 364:              InverseDWT_2D(component, 1);
 365:          }
 366:   
 367:          private static void InverseDWT_2D(short[,] data2D, int pass)
 368:          {
 369:              //level > 0
 370:              //data2D.Length % (1<<(level - 1)) == 0
 371:              int inScopelen;
 372:              switch (pass)
 373:              {
 374:                  case 1:
 375:                      {
 376:                          // First pass
 377:                          inScopelen = 64;
 378:                          break;
 379:                      }
 380:                  case 2:
 381:                      {
 382:                          // Second pass
 383:                          inScopelen = 33;
 384:                          break;
 385:                      }
 386:                  case 3:
 387:                      {
 388:                          // Third pass
 389:                          inScopelen = 17;
 390:                          break;
 391:                      }
 392:                  default:
 393:                      {
 394:                          throw new InvalidOperationException("DWT_2D: the parameter level should only be 1, 2, or 3.");
 395:                      }
 396:              }
 397:   
 398:              //Horizontal DWT
 399:              for (int y = 0; y < inScopelen; y++)
 400:              {
 401:                  short[] row;
 402:                 RemoteFXDecoder.getRowFrom2DArr<short>(data2D, out row, y, inScopelen);
 403:                  row = InverseDWT_1D(row);
 404:                  for (int x = 0; x < inScopelen; x++)
 405:                  {
 406:                      data2D[x, y] = row[x];
 407:                  }
 408:              }
 409:   
 410:              //Vertical DWT
 411:              for (int x = 0; x < inScopelen; x++)
 412:              {
 413:                  short[] col;
 414:                  RemoteFXDecoder.getColFrom2DArr<short>(data2D, out col, x, inScopelen);
 415:                  col = InverseDWT_1D(col);
 416:                  for (int y = 0; y < inScopelen; y++)
 417:                  {
 418:                      data2D[x, y] = col[y];
 419:                  }
 420:              }
 421:          }
 422:   
 423:          public static short[] InverseDWT_1D(short[] elements)
 424:          {
 425:              int hOffset = elements.Length / 2 + 1;
 426:              short[] encodedData;
 427:              if (elements.Length == RdpegfxTileUtils.TileSize)
 428:              {
 429:                  //first pass
 430:                  encodedData = new short[elements.Length + 1];
 431:                  Array.Copy(elements, encodedData, elements.Length);
 432:                  encodedData[elements.Length] = 0;
 433:              }
 434:              else
 435:              {
 436:                  encodedData = elements;
 437:              }
 438:              int hLen = encodedData.Length - hOffset;
 439:              short[] decodedData = new short[encodedData.Length];
 440:              for (int i = 1; 2 * i < encodedData.Length - 1; i++)
 441:              {
 442:                  //X[2n] = L[n] - (H[n-1] + H[n] + 1) / 2
 443:                  //decodedData[2 * i] = (short)Math.Round(encodedData[i] - (encodedData[hOffset + i - 1] + encodedData[hOffset + i] + 1.0f) / 2);
 444:                  decodedData[2 * i] = (short)(encodedData[i] - ((encodedData[hOffset + i - 1] + encodedData[hOffset + i] + 1) >> 1));
 445:              }
 446:   
 447:              //decodedData[decodedData.Length - 1] = (short)Math.Round(2 * decodedData[decodedData.Length - 2] - 4 * encodedData[hOffset + hLen - 1] - decodedData[decodedData.Length - 3] + 0.0f);
 448:              decodedData[decodedData.Length - 1] = (short)Math.Round(encodedData[hOffset - 1] - encodedData[hOffset + hLen - 1] - 0.5f);
 449:              for (int i = 1; 2 * i + 2 < encodedData.Length; i++)
 450:              {
 451:                  //X[2n + 1] = 2*H[n] + (X[2n] + X[2n + 2])/2
 452:                  //decodedData[2 * i + 1] = (short)Math.Round(2 * encodedData[hOffset + i] + (decodedData[2 * i] + decodedData[2 * i + 2] + 0.0f) / 2);
 453:                  decodedData[2 * i + 1] = (short)(2 * encodedData[hOffset + i] + ((decodedData[2 * i] + decodedData[2 * i + 2]) >> 1));
 454:              }
 455:   
 456:              //Handle X[0], [1], [len-1]
 457:              //H(-1) = H[0]
 458:              decodedData[0] = (short)Math.Round(encodedData[0] - (encodedData[hOffset] + encodedData[hOffset] + 1.0f) / 2);
 459:              decodedData[1] = (short)Math.Round(2 * encodedData[hOffset] + (decodedData[0] + decodedData[2] + 0.0f) / 2);
 460:              //decodedData[decodedData.Length - 1] = (short)(2 * encodedData[hOffset + hLen - 1] + decodedData[decodedData.Length - 2]);
 461:              //decodedData[decodedData.Length - 1] = (short)Math.Round(encodedData[hOffset - 1] - (2 * encodedData[hOffset + hLen - 1] + 1.0f) / 2);
 462:   
 463:              short[] reElements;
 464:              if (decodedData.Length > elements.Length)
 465:              {
 466:                  reElements = new short[elements.Length];
 467:                  Array.Copy(decodedData, reElements, reElements.Length);
 468:              }
 469:              else
 470:              {
 471:                  reElements = decodedData;
 472:              }
 473:              return reElements;
 474:          }
 475:   
 476:          #endregion
 477:   
 478:          #region Dequantization
 479:          public static void Dequantization(RfxProgressiveCodecContext codecContext)
 480:          {
 481:              dequantization_Component(codecContext.YSet, codecContext.CodecQuantVals[codecContext.QuantIdxY], codecContext.UseReduceExtrapolate);
 482:              dequantization_Component(codecContext.CbSet, codecContext.CodecQuantVals[codecContext.QuantIdxCb], codecContext.UseReduceExtrapolate);
 483:              dequantization_Component(codecContext.CrSet, codecContext.CodecQuantVals[codecContext.QuantIdxCr], codecContext.UseReduceExtrapolate);
 484:          }
 485:   
 486:          protected static void dequantization_Component(short[,] compontent, TS_RFX_CODEC_QUANT tsRfxCodecQuant, bool useReduceExtrapolate)
 487:          {
 488:              // Quantization factor: HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, LL3            
 489:              Hashtable scaleValueTable = new Hashtable();
 490:              int HL1_Factor = tsRfxCodecQuant.HL1_HH1 & 0x0f;
 491:              int LH1_Factor = (tsRfxCodecQuant.HH2_LH1 & 0xf0) >> 4;
 492:              int HH1_Factor = (tsRfxCodecQuant.HL1_HH1 & 0xf0) >> 4;
 493:              int HL2_Factor = (tsRfxCodecQuant.LH2_HL2 & 0xf0) >> 4;
 494:              int LH2_Factor = tsRfxCodecQuant.LH2_HL2 & 0x0f;
 495:              int HH2_Factor = tsRfxCodecQuant.HH2_LH1 & 0x0f;
 496:              int HL3_Factor = tsRfxCodecQuant.HL3_HH3 & 0x0f;
 497:              int LH3_Factor = (tsRfxCodecQuant.LL3_LH3 & 0xf0) >> 4;
 498:              int HH3_Factor = (tsRfxCodecQuant.HL3_HH3 & 0xf0) >> 4;
 499:              int LL3_Factor = tsRfxCodecQuant.LL3_LH3 & 0x0f;
 500:              int[] HL_Factor = { HL1_Factor, HL2_Factor, HL3_Factor };
 501:              int[] LH_Factor = { LH1_Factor, LH2_Factor, LH3_Factor };
 502:              int[] HH_Factor = { HH1_Factor, HH2_Factor, HH3_Factor };
 503:   
 504:              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 };
 505:              int[] bandFactor = new int[] { HL1_Factor, LH1_Factor, HH1_Factor, HL2_Factor, LH2_Factor, HH2_Factor, HL3_Factor, LH3_Factor, HH3_Factor, LL3_Factor };
 506:   
 507:              for (int i = 0; i < bandArr.Length; i++)
 508:              {
 509:                  BandRect br = RdpegfxTileUtils.GetBandRect(bandArr[i], useReduceExtrapolate);
 510:                  doDequantization_Subband(compontent, br.left, br.top, br.right, br.bottom, bandFactor[i]);
 511:              }
 512:          }
 513:   
 514:          private static void doDequantization_Subband(short[,] input, int left, int top, int right, int bottom, int factor)
 515:          {
 516:              for (int x = left; x <= right; x++)
 517:              {
 518:                  for (int y = top; y <= bottom; y++)
 519:                  {
 520:                      input[x, y] = (short)(input[x, y] << (factor - 6));//<< DWT_PREC);
 521:                  }
 522:              }
 523:          }
 524:          #endregion
 525:   
 526:          #region Progressive Dequantization
 527:   
 528:          public static void ProgressiveDeQuantization(RfxProgressiveCodecContext codecContext, RFX_PROGRESSIVE_CODEC_QUANT progCodecQuant )
 529:          {
 530:              ProgressiveDeQuantization_Component(codecContext.YComponent,  progCodecQuant.yQuantValues, codecContext.UseReduceExtrapolate);
 531:              ProgressiveDeQuantization_Component(codecContext.CbComponent,  progCodecQuant.cbQuantValues, codecContext.UseReduceExtrapolate);
 532:              ProgressiveDeQuantization_Component(codecContext.CrComponent, progCodecQuant.crQuantValues, codecContext.UseReduceExtrapolate);
 533:          }
 534:   
 535:          protected static void ProgressiveDeQuantization_Component(short[] data, RFX_COMPONMENT_CODEC_QUANT quant, bool useReduceExtrapolate)
 536:          {
 537:              int bitPos = 0;
 538:              for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
 539:              {
 540:                  BandType_Values band = RdpegfxTileUtils.GetBandByIndex(i, useReduceExtrapolate);
 541:                  bitPos = RdpegfxTileUtils.GetBitPosFromQuant(quant, band);
 542:                  data[i] = FunProgDeQ(data[i], bitPos, band);
 543:              }
 544:          }
 545:   
 546:          static short FunProgDeQ(short v, int bitPos, BandType_Values band)
 547:          {
 548:              if (band != BandType_Values.LL3)
 549:              {
 550:                  if (v >= 0) return (short)(v << bitPos);
 551:                  return (short)-((-v) << bitPos);
 552:              }
 553:              else
 554:              {
 555:                  return (short)(v << bitPos);
 556:              }
 557:          }
 558:          #endregion
 559:   
 560:          static DwtTile SetTriState(DwtTile inputTile, bool useReduceExtrapolate)
 561:          {
 562:              int ll3Len = RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, useReduceExtrapolate);
 563:              int ll3Idx = RdpegfxTileUtils.ComponentElementCount - ll3Len;
 564:   
 565:              DwtTile stateTile = new DwtTile(
 566:                  new short[RdpegfxTileUtils.ComponentElementCount], //y state
 567:                  new short[RdpegfxTileUtils.ComponentElementCount], //cb state
 568:                  new short[RdpegfxTileUtils.ComponentElementCount]); //cr state
 569:   
 570:              for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
 571:              {
 572:                  if (i < ll3Idx)
 573:                  {
 574:                      stateTile.Y_DwtQ[i] = (short)Math.Sign(inputTile.Y_DwtQ[i]);
 575:                      stateTile.Cb_DwtQ[i] = (short)Math.Sign(inputTile.Cb_DwtQ[i]);
 576:                      stateTile.Cr_DwtQ[i] = (short)Math.Sign(inputTile.Cr_DwtQ[i]);
 577:                  }
 578:                  else
 579:                  {
 580:                      stateTile.Y_DwtQ[i] = 1;
 581:                      stateTile.Cb_DwtQ[i] = 1;
 582:                      stateTile.Cr_DwtQ[i] = 1;
 583:                  }
 584:              }
 585:              return stateTile;
 586:          }
 587:      }
 588:  }