/// <summary>
        /// Build tile data blocks(tile simple or tile first or tile upgrade).
        /// </summary>
        /// <param name="quantIdx">This is used to indicate index in TS_RFX_CODEC_QUANT array of region block</param>
        /// <param name="tileIdx">This is used to indicate the tile index.</param>
        /// <param name="tileData">This is used to indicate the encoded tile data.</param>
        /// <param name="tileBlockType">This is used to indicate the tile data block type(simple, first, or upgrade).</param>
        public RFX_Progressive_DataBlock BuildTileDataBlock(byte quantIdx, TileIndex tileIdx, EncodedTile tileData, RFXProgCodecBlockType tileBlockType)
        {
            RFX_Progressive_DataBlock tile_block;

            if (tileBlockType == RFXProgCodecBlockType.WBT_TILE_PROGRESSIVE_FIRST)
            {
                tile_block = new RFX_Progressive_TILE_FIRST(quantIdx, tileIdx, tileData);
            }
            else if (tileBlockType == RFXProgCodecBlockType.WBT_TILE_PROGRESSIVE_UPGRADE)
            {
                tile_block = new RFX_PROGRESSIVE_TILE_UPGRADE(quantIdx, tileIdx, tileData);
            }
            else
            {
                tile_block = new RFX_Progressive_TILE_SIMPLE(quantIdx, tileIdx, tileData);
            }

            return tile_block;
        }
        /// <summary>
        /// Constructor, create RFX_PROGRESSIVE_TILE_UPGRADE block 
        /// </summary>
        /// <param name="quantIdx">This is used to indicate index in TS_RFX_CODEC_AUANT array of region block</param>
        /// <param name="tileIdx">This is used to indicate tile position([x, y]).</param>
        /// <param name="tileData">This is used to indicate encoded tile data which is related to quantIdx</param>
        public RFX_PROGRESSIVE_TILE_UPGRADE(byte quantIdx, TileIndex tileIdx, EncodedTile tileData)
        {
            this.blockType = RFXProgCodecBlockType.WBT_TILE_PROGRESSIVE_UPGRADE;
            this.blockLen = 6;  // Common part 6 bytes.

            this.quantIdxY = quantIdx;
            this.quantIdxCb = quantIdx;
            this.quantIdxCr = quantIdx;

            this.xIdx = tileIdx.X;
            this.yIdx = tileIdx.Y;

            this.progressiveQuality = tileData.ProgCodecQuant.quality;
            this.blockLen += 8;

            // Srl data.
            this.ySrlLen = (tileData.YEncodedData == null) ? (ushort)0 : (ushort)tileData.YEncodedData.Count();
            this.ySrlData = tileData.YEncodedData;

            this.cbSrlLen = (tileData.CbEncodedData == null) ? (ushort)0 : (ushort)tileData.CbEncodedData.Count();
            this.cbSrlData = tileData.CbEncodedData;
            this.crSrlLen = (tileData.CrEncodedData == null) ? (ushort)0 : (ushort)tileData.CrEncodedData.Count();
            this.crSrlData = tileData.CrEncodedData;
            this.blockLen += (uint)(6 + this.ySrlLen + this.cbSrlLen + this.crSrlLen);

            // Raw data.
            this.yRawLen = (tileData.YRawData == null) ? (ushort)0 : (ushort)tileData.YRawData.Count();
            this.yRawData = tileData.YRawData;
            this.cbRawLen = (tileData.CbRawData == null) ? (ushort)0 : (ushort)tileData.CbRawData.Count();
            this.cbRawData = tileData.CbRawData;
            this.crRawLen = (tileData.CrRawData == null) ? (ushort)0 : (ushort)tileData.CrRawData.Count();
            this.crRawData = tileData.CrRawData;
            this.blockLen += (uint)(6 + this.yRawLen + this.cbRawLen + this.crRawLen);
        }
        /// <summary>
        /// constructor, create RFX_Progressive_REGION block 
        /// </summary>
        /// <param name="bProg">This is used to indicate if progressive encoding is enabled </param>
        /// <param name="flag">This is used to indicate region flag </param>
        /// <param name="tileDSize">This is used to indicate total size of all tiles encoded data </param>
        /// <param name="regionRects">This is used to indicate region rectangles that all tiles to fill </param>
        /// <param name="tileDataArr">This is used to indicate quant data for specific layer </param>
        public RFX_Progressive_REGION(bool bProg, byte flag, uint tileDSize, TS_RFX_RECT[] regionRects, EncodedTile[] tileDataArr)
        {
            this.blockType = RFXProgCodecBlockType.WBT_REGION;
            this.blockLen = 6;  // common part 6 bytes

            this.tileSize = (byte)RFX_Progressive_CONST.CONTEXT_TILESIZE;
            this.flags = flag;
            this.blockLen += 2;

            // Init rect.
            this.numRects = (ushort)regionRects.Count();
            this.rects = regionRects;
            this.blockLen += (uint)(2 + this.numRects * Marshal.SizeOf(this.rects[0]));

            // Init quant array.
            this.numQuant = (byte)tileDataArr[0].CodecQuantVals.Length;      // each tile share same quantity table
            this.blockLen += 1;
            this.quantVals = tileDataArr[0].CodecQuantVals;
            this.blockLen += (uint)(this.numQuant * 5);

            if (bProg)  // Progressive encoding.
            {
                this.numProgQuant = 1;  // Each tile share same progressive quantity table.
                this.blockLen += 1;
                this.quantProgVals = new RFX_PROGRESSIVE_CODEC_QUANT[this.numProgQuant];
                for (int i = 0; i < this.numProgQuant; i++)
                {
                    this.quantProgVals[i] = tileDataArr[i].ProgCodecQuant;
                    this.blockLen += (uint)(1 + Marshal.SizeOf(this.quantProgVals[i].yQuantValues) +
                                            Marshal.SizeOf(this.quantProgVals[i].cbQuantValues) +
                                            Marshal.SizeOf(this.quantProgVals[i].crQuantValues));
                }
            }
            else  // Non-progressive encoding.
            {
                this.numProgQuant = 0;
                this.blockLen += 1;
                this.quantProgVals = null;
            }

            this.numTiles = (ushort)tileDataArr.Count();
            this.tileDataSize = tileDSize;
            this.blockLen += (6 + tileDSize);
        }
        /// <summary>
        /// Encode a Tile
        /// </summary>
        /// <param name="encodingContext">The tile encoding context</param>
        /// <param name="enTileInfo">The tile to be encoded</param>
        /// <returns>A array of CompressedTile which contains the encoded tiles</returns>
        public static EncodedTile[] EncodeTile(RfxProgressiveCodecContext encodingContext, TileState enTileInfo)
        {
            EncodedTileType targetType = encodingContext.UseProgressive ? EncodedTileType.FirstPass : EncodedTileType.Simple;

            //File RGB
            FillRgbData(encodingContext, enTileInfo.GetRgb());

            //Do color conversion
            RemoteFXEncoder.RGBToYCbCr(encodingContext);

            //Do DWT
            if (encodingContext.UseReduceExtrapolate)
            {
                //Do DWT using UseReduce Extrapolate method
                DWT(encodingContext);
            }
            else
            {
                RemoteFXEncoder.DWT(encodingContext);
            }

            //Do quantiztion
            Quantization(encodingContext);

            //Do linearization (LL3 delta not computed)
            Linearization_NoLL3Delta(encodingContext);

            //Update new DWT to tile
            DwtTile dwt = new DwtTile(
                (short[])encodingContext.YComponent.Clone(),
                (short[])encodingContext.CbComponent.Clone(),
                (short[])encodingContext.CrComponent.Clone(),
                encodingContext.CodecQuantVals,
                encodingContext.QuantIdxY,
                encodingContext.QuantIdxCb,
                encodingContext.QuantIdxCr,
                encodingContext.UseReduceExtrapolate
                );
            enTileInfo.UpdateDwt(dwt);

            //Sub-Band Diffing
            if (encodingContext.UseDifferenceTile)
            {
                SubBandDiffing_DT(encodingContext, enTileInfo);
            }

            if (targetType == EncodedTileType.Simple)
            {
                ComputeLL3Deltas(encodingContext);

                RemoteFXEncoder.RLGREncode(encodingContext);
                EncodedTile cpTile = new EncodedTile();
                cpTile.YEncodedData = (byte[])encodingContext.YData.Clone();
                cpTile.CbEncodedData = (byte[])encodingContext.CbData.Clone();
                cpTile.CrEncodedData = (byte[])encodingContext.CrData.Clone();
                cpTile.DataType = EncodedTileType.Simple;
                cpTile.IsDifferenceTile = encodingContext.UseDifferenceTile;
                cpTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
                cpTile.CodecQuantVals = encodingContext.CodecQuantVals;
                cpTile.QuantIdxY = encodingContext.QuantIdxY;
                cpTile.QuantIdxCb = encodingContext.QuantIdxCb;
                cpTile.QuantIdxCr = encodingContext.QuantIdxCr;
                cpTile.ProgCodecQuant = null;
                return new EncodedTile[] { cpTile };
            }
            else
            {
                List<EncodedTile> progCTileList = new List<EncodedTile>();
                //Init DRS, DAS
                encodingContext.DRS = new DwtTile(encodingContext.YComponent, encodingContext.CbComponent, encodingContext.CrComponent);
                encodingContext.DAS = new DwtTile(new short[RdpegfxTileUtils.ComponentElementCount], new short[RdpegfxTileUtils.ComponentElementCount], new short[RdpegfxTileUtils.ComponentElementCount]);

                #region Chunk 25, first pass

                ProgressiveQuantization(encodingContext, ProgressiveChunk_Values.kChunk_25);

                //Compute ProgQ LL3 deltas
                encodingContext.YComponent = encodingContext.ProgQ.Y_DwtQ;
                encodingContext.CbComponent = encodingContext.ProgQ.Cb_DwtQ;
                encodingContext.CrComponent = encodingContext.ProgQ.Cr_DwtQ;

                ComputeLL3Deltas(encodingContext);

                RemoteFXEncoder.RLGREncode(encodingContext);
                EncodedTile firstPassTile = new EncodedTile();
                firstPassTile.YEncodedData = (byte[])encodingContext.YData.Clone();
                firstPassTile.CbEncodedData = (byte[])encodingContext.CbData.Clone();
                firstPassTile.CrEncodedData = (byte[])encodingContext.CrData.Clone();
                firstPassTile.DataType = EncodedTileType.FirstPass;
                firstPassTile.IsDifferenceTile = encodingContext.UseDifferenceTile;
                firstPassTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
                firstPassTile.CodecQuantVals = encodingContext.CodecQuantVals;
                firstPassTile.QuantIdxY = encodingContext.QuantIdxY;
                firstPassTile.QuantIdxCb = encodingContext.QuantIdxCb;
                firstPassTile.QuantIdxCr = encodingContext.QuantIdxCr;
                firstPassTile.ProgCodecQuant = RdpegfxTileUtils.GetProgCodecQuant(ProgressiveChunk_Values.kChunk_25);
                progCTileList.Add(firstPassTile);
                encodingContext.prevProgQuant = RdpegfxTileUtils.GetProgCodecQuant(ProgressiveChunk_Values.kChunk_25);

                //Update DRS
                encodingContext.DRS.Sub(encodingContext.DTS);
                //Update DAS
                encodingContext.DAS.Add(encodingContext.DTS);
                #endregion

                #region Chunk 50,75,100, upgrade pass
                ProgressiveChunk_Values[] upgradeChunks = { ProgressiveChunk_Values.kChunk_50, ProgressiveChunk_Values.kChunk_75, ProgressiveChunk_Values.kChunk_100 };

                foreach (ProgressiveChunk_Values tChunk in upgradeChunks)
                {
                    ProgressiveQuantization(encodingContext, tChunk);

                    RFX_PROGRESSIVE_CODEC_QUANT progquant = RdpegfxTileUtils.GetProgCodecQuant(tChunk);

                    progCTileList.Add(SRLEncode(encodingContext, progquant));

                    //Update DRS
                    encodingContext.DRS.Sub(encodingContext.DTS);
                    //Update DAS
                    encodingContext.DAS.Add(encodingContext.DTS);

                    encodingContext.prevProgQuant = progquant;
                }

                return progCTileList.ToArray();

                #endregion

            }
        }
        /// <summary>
        /// constructor, create RFX_Progressive_TILE_SIMPLE block 
        /// </summary>
        /// <param name="quantIdx">This is used to indicate index in TS_RFX_CODEC_AUANT array of region block</param>
        /// <param name="tileIdx">This is used to indicate tile position([x, y]).</param>
        /// <param name="tileData">This is used to indicate encoded tile data</param>
        public RFX_Progressive_TILE_SIMPLE(byte quantIdx, TileIndex tileIdx, EncodedTile tileData)
        {
            this.blockType = RFXProgCodecBlockType.WBT_TILE_SIMPLE;
            this.blockLen = 6;  // common part 6 bytes

            this.quantIdxY = quantIdx;
            this.quantIdxCb = quantIdx;
            this.quantIdxCr = quantIdx;

            this.xIdx = tileIdx.X;
            this.yIdx = tileIdx.Y;

            this.flags = tileData.IsDifferenceTile;
            this.blockLen += 8;

            this.yLen = (tileData.YEncodedData == null) ? (ushort)0 : (ushort)tileData.YEncodedData.Count();
            this.yData = tileData.YEncodedData;
            this.blockLen += (uint)(2 + this.yLen);

            this.cbLen = (tileData.CbEncodedData == null) ? (ushort)0 : (ushort)tileData.CbEncodedData.Count();
            this.cbData = tileData.CbEncodedData;
            this.blockLen += (uint)(2 + this.cbLen);

            this.crLen = (tileData.CrEncodedData == null) ? (ushort)0 : (ushort)tileData.CrEncodedData.Count();
            this.crData = tileData.CrEncodedData;
            this.blockLen += (uint)(2 + this.crLen);

            //this.tailLen = 8;
            //this.tailData = new byte[8]{0x4C, 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x10};
            this.tailLen = 0;
            this.tailData = null;
            this.blockLen += (uint)(2 + this.tailLen);
        }
예제 #6
0
        //SRLEncode
        public static EncodedTile SRLEncode(RfxProgressiveCodecContext encodingContext, Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT progQuant)
        {
            SRLEncoder encoder = new SRLEncoder();

            List <short> yDataToSrl  = new List <short>();
            List <short> cbDataToSrl = new List <short>();
            List <short> crDataToSrl = new List <short>();

            List <int> yDataToSrlBitLen  = new List <int>();
            List <int> cbDataToSrlBitLen = new List <int>();
            List <int> crDataToSrlBitLen = new List <int>();

            BitStream yRawBitStream  = new BitStream();
            BitStream cbRawBitStream = new BitStream();
            BitStream crRawBitStream = new BitStream();

            int nonLL3Len = RdpegfxTileUtils.ComponentElementCount - RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, encodingContext.UseReduceExtrapolate);

            Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT prevProgQuant = encodingContext.prevProgQuant;
            Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT curProgQuant  = progQuant;

            for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
            {
                BandType_Values band = RdpegfxTileUtils.GetBandByIndex(i, encodingContext.UseReduceExtrapolate);

                int targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.yQuantValues, band);
                int prevBitPos   = RdpegfxTileUtils.GetBitPosFromQuant(prevProgQuant.yQuantValues, band);
                int bitCount     = prevBitPos - targetBitPos;
                if (bitCount > 0)
                {
                    if (encodingContext.DAS.Y_DwtQ[i] == 0 && i < nonLL3Len)
                    {
                        yDataToSrl.Add(encodingContext.ProgQ.Y_DwtQ[i]);
                        yDataToSrlBitLen.Add(bitCount);
                    }
                    else
                    {
                        //Add raw data
                        yRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Y_DwtQ[i]));
                    }
                }

                targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.cbQuantValues, band);
                prevBitPos   = RdpegfxTileUtils.GetBitPosFromQuant(prevProgQuant.cbQuantValues, band);
                bitCount     = prevBitPos - targetBitPos;
                if (bitCount > 0)
                {
                    if (encodingContext.DAS.Cb_DwtQ[i] == 0 && i < nonLL3Len)
                    {
                        cbDataToSrl.Add(encodingContext.ProgQ.Cb_DwtQ[i]);
                        cbDataToSrlBitLen.Add(bitCount);
                    }
                    else
                    {
                        //Add raw data
                        cbRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Cb_DwtQ[i]));
                    }
                }

                targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.crQuantValues, band);
                prevBitPos   = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.crQuantValues, band);
                bitCount     = prevBitPos - targetBitPos;
                if (bitCount > 0)
                {
                    if (encodingContext.DAS.Cr_DwtQ[i] == 0 && i < nonLL3Len)
                    {
                        crDataToSrl.Add(encodingContext.ProgQ.Cr_DwtQ[i]);
                        crDataToSrlBitLen.Add(bitCount);
                    }
                    else
                    {
                        //Add raw data
                        crRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Cr_DwtQ[i]));
                    }
                }
            }

            encodingContext.YData  = encoder.Encode(yDataToSrl.ToArray(), yDataToSrlBitLen.ToArray());
            encodingContext.CbData = encoder.Encode(cbDataToSrl.ToArray(), cbDataToSrlBitLen.ToArray());
            encodingContext.CrData = encoder.Encode(crDataToSrl.ToArray(), crDataToSrlBitLen.ToArray());

            EncodedTile ugTile = new EncodedTile();

            ugTile.YEncodedData         = (byte[])encodingContext.YData.Clone();
            ugTile.CbEncodedData        = (byte[])encodingContext.CbData.Clone();
            ugTile.CrEncodedData        = (byte[])encodingContext.CrData.Clone();
            ugTile.YRawData             = yRawBitStream.ToBytes();
            ugTile.CbRawData            = cbRawBitStream.ToBytes();
            ugTile.CrRawData            = crRawBitStream.ToBytes();
            ugTile.DataType             = EncodedTileType.UpgradePass;
            ugTile.IsDifferenceTile     = encodingContext.UseDifferenceTile;
            ugTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
            ugTile.CodecQuantVals       = encodingContext.CodecQuantVals;
            ugTile.QuantIdxY            = encodingContext.QuantIdxY;
            ugTile.QuantIdxCb           = encodingContext.QuantIdxCb;
            ugTile.QuantIdxCr           = encodingContext.QuantIdxCr;
            ugTile.ProgCodecQuant       = curProgQuant;

            return(ugTile);
        }
        //SRLEncode
        public static EncodedTile SRLEncode(RfxProgressiveCodecContext encodingContext, Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT progQuant)
        {
            SRLEncoder encoder = new SRLEncoder();

            List<short> yDataToSrl = new List<short>();
            List<short> cbDataToSrl = new List<short>();
            List<short> crDataToSrl = new List<short>();

            List<int> yDataToSrlBitLen = new List<int>();
            List<int> cbDataToSrlBitLen = new List<int>();
            List<int> crDataToSrlBitLen = new List<int>();

            BitStream yRawBitStream = new BitStream();
            BitStream cbRawBitStream = new BitStream();
            BitStream crRawBitStream = new BitStream();

            int nonLL3Len = RdpegfxTileUtils.ComponentElementCount - RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, encodingContext.UseReduceExtrapolate);
            Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT prevProgQuant = encodingContext.prevProgQuant;
            Rdpegfx.RFX_PROGRESSIVE_CODEC_QUANT curProgQuant = progQuant;

            for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
            {
                BandType_Values band = RdpegfxTileUtils.GetBandByIndex(i, encodingContext.UseReduceExtrapolate);

                int targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.yQuantValues, band);
                int prevBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prevProgQuant.yQuantValues, band);
                int bitCount = prevBitPos - targetBitPos;
                if (bitCount > 0)
                {
                    if (encodingContext.DAS.Y_DwtQ[i] == 0 && i < nonLL3Len)
                    {
                        yDataToSrl.Add(encodingContext.ProgQ.Y_DwtQ[i]);
                        yDataToSrlBitLen.Add(bitCount);
                    }
                    else
                    {
                        //Add raw data
                        yRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Y_DwtQ[i]));
                    }
                }

                targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.cbQuantValues, band);
                prevBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prevProgQuant.cbQuantValues, band);
                bitCount = prevBitPos - targetBitPos;
                if (bitCount > 0)
                {
                    if (encodingContext.DAS.Cb_DwtQ[i] == 0 && i < nonLL3Len)
                    {
                        cbDataToSrl.Add(encodingContext.ProgQ.Cb_DwtQ[i]);
                        cbDataToSrlBitLen.Add(bitCount);
                    }
                    else
                    {
                        //Add raw data
                        cbRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Cb_DwtQ[i]));
                    }
                }

                targetBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.crQuantValues, band);
                prevBitPos = RdpegfxTileUtils.GetBitPosFromQuant(curProgQuant.crQuantValues, band);
                bitCount = prevBitPos - targetBitPos;
                if (bitCount > 0)
                {
                    if (encodingContext.DAS.Cr_DwtQ[i] == 0 && i < nonLL3Len)
                    {
                        crDataToSrl.Add(encodingContext.ProgQ.Cr_DwtQ[i]);
                        crDataToSrlBitLen.Add(bitCount);
                    }
                    else
                    {
                        //Add raw data
                        crRawBitStream.WriteBits(bitCount, Math.Abs(encodingContext.ProgQ.Cr_DwtQ[i]));
                    }
                }
            }

            encodingContext.YData = encoder.Encode(yDataToSrl.ToArray(), yDataToSrlBitLen.ToArray());
            encodingContext.CbData = encoder.Encode(cbDataToSrl.ToArray(), cbDataToSrlBitLen.ToArray());
            encodingContext.CrData = encoder.Encode(crDataToSrl.ToArray(), crDataToSrlBitLen.ToArray());

            EncodedTile ugTile = new EncodedTile();
            ugTile.YEncodedData = (byte[])encodingContext.YData.Clone();
            ugTile.CbEncodedData = (byte[])encodingContext.CbData.Clone();
            ugTile.CrEncodedData = (byte[])encodingContext.CrData.Clone();
            ugTile.YRawData = yRawBitStream.ToBytes();
            ugTile.CbRawData = cbRawBitStream.ToBytes();
            ugTile.CrRawData = crRawBitStream.ToBytes();
            ugTile.DataType = EncodedTileType.UpgradePass;
            ugTile.IsDifferenceTile = encodingContext.UseDifferenceTile;
            ugTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
            ugTile.CodecQuantVals = encodingContext.CodecQuantVals;
            ugTile.QuantIdxY = encodingContext.QuantIdxY;
            ugTile.QuantIdxCb = encodingContext.QuantIdxCb;
            ugTile.QuantIdxCr = encodingContext.QuantIdxCr;
            ugTile.ProgCodecQuant = curProgQuant;

            return ugTile;
        }
예제 #8
0
        /// <summary>
        /// Encode a Tile
        /// </summary>
        /// <param name="encodingContext">The tile encoding context</param>
        /// <param name="enTileInfo">The tile to be encoded</param>
        /// <returns>A array of CompressedTile which contains the encoded tiles</returns>
        public static EncodedTile[] EncodeTile(RfxProgressiveCodecContext encodingContext, TileState enTileInfo)
        {
            EncodedTileType targetType = encodingContext.UseProgressive ? EncodedTileType.FirstPass : EncodedTileType.Simple;

            //File RGB
            FillRgbData(encodingContext, enTileInfo.GetRgb());

            //Do color conversion
            RemoteFXEncoder.RGBToYCbCr(encodingContext);

            //Do DWT
            if (encodingContext.UseReduceExtrapolate)
            {
                //Do DWT using UseReduce Extrapolate method
                DWT(encodingContext);
            }
            else
            {
                RemoteFXEncoder.DWT(encodingContext);
            }

            //Do quantiztion
            Quantization(encodingContext);

            //Do linearization (LL3 delta not computed)
            Linearization_NoLL3Delta(encodingContext);

            //Update new DWT to tile
            DwtTile dwt = new DwtTile(
                (short[])encodingContext.YComponent.Clone(),
                (short[])encodingContext.CbComponent.Clone(),
                (short[])encodingContext.CrComponent.Clone(),
                encodingContext.CodecQuantVals,
                encodingContext.QuantIdxY,
                encodingContext.QuantIdxCb,
                encodingContext.QuantIdxCr,
                encodingContext.UseReduceExtrapolate
                );

            enTileInfo.UpdateDwt(dwt);


            //Sub-Band Diffing
            if (encodingContext.UseDifferenceTile)
            {
                SubBandDiffing_DT(encodingContext, enTileInfo);
            }

            if (targetType == EncodedTileType.Simple)
            {
                ComputeLL3Deltas(encodingContext);

                RemoteFXEncoder.RLGREncode(encodingContext);
                EncodedTile cpTile = new EncodedTile();
                cpTile.YEncodedData         = (byte[])encodingContext.YData.Clone();
                cpTile.CbEncodedData        = (byte[])encodingContext.CbData.Clone();
                cpTile.CrEncodedData        = (byte[])encodingContext.CrData.Clone();
                cpTile.DataType             = EncodedTileType.Simple;
                cpTile.IsDifferenceTile     = encodingContext.UseDifferenceTile;
                cpTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
                cpTile.CodecQuantVals       = encodingContext.CodecQuantVals;
                cpTile.QuantIdxY            = encodingContext.QuantIdxY;
                cpTile.QuantIdxCb           = encodingContext.QuantIdxCb;
                cpTile.QuantIdxCr           = encodingContext.QuantIdxCr;
                cpTile.ProgCodecQuant       = null;
                return(new EncodedTile[] { cpTile });
            }
            else
            {
                List <EncodedTile> progCTileList = new List <EncodedTile>();
                //Init DRS, DAS
                encodingContext.DRS = new DwtTile(encodingContext.YComponent, encodingContext.CbComponent, encodingContext.CrComponent);
                encodingContext.DAS = new DwtTile(new short[RdpegfxTileUtils.ComponentElementCount], new short[RdpegfxTileUtils.ComponentElementCount], new short[RdpegfxTileUtils.ComponentElementCount]);

                #region Chunk 25, first pass

                ProgressiveQuantization(encodingContext, ProgressiveChunk_Values.kChunk_25);

                //Compute ProgQ LL3 deltas
                encodingContext.YComponent  = encodingContext.ProgQ.Y_DwtQ;
                encodingContext.CbComponent = encodingContext.ProgQ.Cb_DwtQ;
                encodingContext.CrComponent = encodingContext.ProgQ.Cr_DwtQ;

                ComputeLL3Deltas(encodingContext);

                RemoteFXEncoder.RLGREncode(encodingContext);
                EncodedTile firstPassTile = new EncodedTile();
                firstPassTile.YEncodedData         = (byte[])encodingContext.YData.Clone();
                firstPassTile.CbEncodedData        = (byte[])encodingContext.CbData.Clone();
                firstPassTile.CrEncodedData        = (byte[])encodingContext.CrData.Clone();
                firstPassTile.DataType             = EncodedTileType.FirstPass;
                firstPassTile.IsDifferenceTile     = encodingContext.UseDifferenceTile;
                firstPassTile.UseReduceExtrapolate = encodingContext.UseReduceExtrapolate;
                firstPassTile.CodecQuantVals       = encodingContext.CodecQuantVals;
                firstPassTile.QuantIdxY            = encodingContext.QuantIdxY;
                firstPassTile.QuantIdxCb           = encodingContext.QuantIdxCb;
                firstPassTile.QuantIdxCr           = encodingContext.QuantIdxCr;
                firstPassTile.ProgCodecQuant       = RdpegfxTileUtils.GetProgCodecQuant(ProgressiveChunk_Values.kChunk_25);
                progCTileList.Add(firstPassTile);
                encodingContext.prevProgQuant = RdpegfxTileUtils.GetProgCodecQuant(ProgressiveChunk_Values.kChunk_25);

                //Update DRS
                encodingContext.DRS.Sub(encodingContext.DTS);
                //Update DAS
                encodingContext.DAS.Add(encodingContext.DTS);
                #endregion

                #region Chunk 50,75,100, upgrade pass
                ProgressiveChunk_Values[] upgradeChunks = { ProgressiveChunk_Values.kChunk_50, ProgressiveChunk_Values.kChunk_75, ProgressiveChunk_Values.kChunk_100 };

                foreach (ProgressiveChunk_Values tChunk in upgradeChunks)
                {
                    ProgressiveQuantization(encodingContext, tChunk);

                    RFX_PROGRESSIVE_CODEC_QUANT progquant = RdpegfxTileUtils.GetProgCodecQuant(tChunk);

                    progCTileList.Add(SRLEncode(encodingContext, progquant));

                    //Update DRS
                    encodingContext.DRS.Sub(encodingContext.DTS);
                    //Update DAS
                    encodingContext.DAS.Add(encodingContext.DTS);

                    encodingContext.prevProgQuant = progquant;
                }

                return(progCTileList.ToArray());

                #endregion
            }
        }
        /// <summary>
        /// Decode an encoded tile
        /// </summary>
        /// <param name="enTile">Represents an encoded tile.</param>
        /// <param name="tState">The context state of the tile that going to be decoded.</param>
        public static void DecodeTile(EncodedTile enTile, TileState tState)
        {
            RfxProgressiveCodecContext codecContext = new RfxProgressiveCodecContext(
                enTile.CodecQuantVals,
                enTile.QuantIdxY,
                enTile.QuantIdxCb,
                enTile.QuantIdxCr,
                enTile.DataType == EncodedTileType.Simple ? false : true,
                enTile.IsDifferenceTile,
                enTile.UseReduceExtrapolate);

            //RLGR/SRL Decode
            if (enTile.DataType == EncodedTileType.FirstPass || enTile.DataType == EncodedTileType.Simple)
            {   //first pass or simple
                codecContext.YData  = enTile.YEncodedData;
                codecContext.CbData = enTile.CbEncodedData;
                codecContext.CrData = enTile.CrEncodedData;
                RemoteFXDecoder.RLGRDecode(codecContext);
                ComputeOriginalLL3FromDeltas(codecContext);
            }
            else
            {
                SRLDecode(codecContext, enTile, tState);
            }

            //Progressive Dequantization
            if (enTile.DataType != EncodedTileType.Simple)
            {
                ProgressiveDeQuantization(codecContext, enTile.ProgCodecQuant);
            }

            // Create a DwtTile instance for tri-state
            DwtTile triStateDwt = new DwtTile(codecContext.YComponent, codecContext.CbComponent, codecContext.CrComponent,
                                              enTile.CodecQuantVals, enTile.QuantIdxY, enTile.QuantIdxCb, enTile.QuantIdxCr, enTile.UseReduceExtrapolate, enTile.ProgCodecQuant);

            //Set Tri-State for progressive codec
            if (enTile.DataType == EncodedTileType.FirstPass)
            {
                //DwtTile tileTriStat = SetTriState(diffDwt, enTile.UseReduceExtrapolate);
                tState.UpdateTriState(triStateDwt);
            }
            else if (enTile.DataType == EncodedTileType.UpgradePass)
            {
                DwtTile prvStat = tState.GetTriState();
                prvStat.Add(triStateDwt);
                // update ProCodecQuant
                prvStat.ProgCodecQuant = triStateDwt.ProgCodecQuant;
                tState.UpdateTriState(prvStat);
            }

            // Create another DwtTile instance for DWT Data.
            // 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
            DwtTile diffDwt = new DwtTile(codecContext.YComponent, codecContext.CbComponent, codecContext.CrComponent,
                                          enTile.CodecQuantVals, enTile.QuantIdxY, enTile.QuantIdxCb, enTile.QuantIdxCr, enTile.UseReduceExtrapolate, enTile.ProgCodecQuant);

            //Sum difference
            if (enTile.IsDifferenceTile || enTile.DataType == EncodedTileType.UpgradePass)
            {
                tState.AddDwt(diffDwt);
            }
            else
            {
                tState.UpdateDwt(diffDwt);
            }
        }
        public static void SRLDecode(RfxProgressiveCodecContext codecContext, EncodedTile enTile, TileState tState)
        {
            SRLDecoder yDecoder  = null;
            SRLDecoder cbDecoder = null;
            SRLDecoder crDecoder = null;

            List <short> yData    = new List <short>();
            List <short> cbData   = new List <short>();
            List <short> crData   = new List <short>();
            DwtTile      triState = tState.GetTriState();
            RFX_PROGRESSIVE_CODEC_QUANT prvProgQuant = tState.GetDwt().ProgCodecQuant;
            int nonLL3Len = RdpegfxTileUtils.ComponentElementCount - RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, enTile.UseReduceExtrapolate);

            if (enTile.YEncodedData != null)
            {
                yDecoder = new SRLDecoder(enTile.YEncodedData);
            }

            if (enTile.CbEncodedData != null)
            {
                cbDecoder = new SRLDecoder(enTile.CbEncodedData);
            }

            if (enTile.CrEncodedData != null)
            {
                crDecoder = new SRLDecoder(enTile.CrEncodedData);
            }

            BitStream yRaw  = BitStream.GetFromBytes(enTile.YRawData);
            BitStream cbRaw = BitStream.GetFromBytes(enTile.CbRawData);
            BitStream crRaw = BitStream.GetFromBytes(enTile.CrRawData);

            for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
            {
                BandType_Values band = RdpegfxTileUtils.GetBandByIndex(i, enTile.UseReduceExtrapolate);

                //Y
                int curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.yQuantValues, band);
                int prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.yQuantValues, band);
                int bitCount  = prvBitPos - curBitPos;
                int sign      = triState.Y_DwtQ[i];
                if (bitCount > 0)
                {
                    if (sign == 0 && i < nonLL3Len)
                    {
                        if (yDecoder != null)
                        {
                            short?decodedValue = yDecoder.DecodeOne(bitCount);
                            if (decodedValue.HasValue)
                            {
                                yData.Add(decodedValue.Value);
                            }
                            else
                            {
                                yData.Add(0);
                            }
                        }
                        else
                        {
                            yData.Add(0);
                        }
                    }
                    else
                    {
                        int output;
                        if (yRaw.ReadInt32(bitCount, out output))
                        {
                            if (sign < 0 && i < nonLL3Len)
                            {
                                output = -output;
                            }
                            yData.Add((short)output);
                        }
                        else
                        {
                            yData.Add(0);
                        }
                    }
                }
                else
                {
                    yData.Add(0);
                }

                //Cb
                curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.cbQuantValues, band);
                prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.cbQuantValues, band);
                bitCount  = prvBitPos - curBitPos;
                sign      = triState.Cb_DwtQ[i];
                if (bitCount > 0)
                {
                    if (sign == 0 && i < nonLL3Len)
                    {
                        if (cbDecoder != null)
                        {
                            short?decodedValue = cbDecoder.DecodeOne(bitCount);
                            if (decodedValue.HasValue)
                            {
                                cbData.Add(decodedValue.Value);
                            }
                            else
                            {
                                cbData.Add(0);
                            }
                        }
                        else
                        {
                            cbData.Add(0);
                        }
                    }
                    else
                    {
                        int output;
                        if (cbRaw.ReadInt32(bitCount, out output))
                        {
                            if (sign < 0 && i < nonLL3Len)
                            {
                                output = -output;
                            }
                            cbData.Add((short)output);
                        }
                        else
                        {
                            cbData.Add(0);
                        }
                    }
                }
                else
                {
                    cbData.Add(0);
                }

                //cr
                curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.crQuantValues, band);
                prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.crQuantValues, band);
                bitCount  = prvBitPos - curBitPos;
                sign      = triState.Cr_DwtQ[i];
                if (bitCount > 0)
                {
                    if (sign == 0 && i < nonLL3Len)
                    {
                        if (crDecoder != null)
                        {
                            short?decodedValue = crDecoder.DecodeOne(bitCount);
                            if (decodedValue.HasValue)
                            {
                                crData.Add(decodedValue.Value);
                            }
                            else
                            {
                                crData.Add(0);
                            }
                        }
                        else
                        {
                            crData.Add(0);
                        }
                    }
                    else
                    {
                        int output;
                        if (crRaw.ReadInt32(bitCount, out output))
                        {
                            if (sign < 0 && i < nonLL3Len)
                            {
                                output = -output;
                            }
                            crData.Add((short)output);
                        }
                        else
                        {
                            crData.Add(0);
                        }
                    }
                }
                else
                {
                    crData.Add(0);
                }
            }

            codecContext.YComponent  = yData.ToArray();
            codecContext.CbComponent = cbData.ToArray();
            codecContext.CrComponent = crData.ToArray();
        }
        /// <summary>
        /// Decode an encoded tile
        /// </summary>
        /// <param name="enTile">Represents an encoded tile.</param>
        /// <param name="tState">The context state of the tile that going to be decoded.</param>
        public static void DecodeTile(EncodedTile enTile, TileState tState)
        {
            RfxProgressiveCodecContext codecContext = new RfxProgressiveCodecContext(
                enTile.CodecQuantVals,
                enTile.QuantIdxY,
                enTile.QuantIdxCb,
                enTile.QuantIdxCr,
                enTile.DataType == EncodedTileType.Simple ? false : true,
                enTile.IsDifferenceTile,
                enTile.UseReduceExtrapolate);

            //RLGR/SRL Decode
            if (enTile.DataType == EncodedTileType.FirstPass || enTile.DataType == EncodedTileType.Simple)
            {   //first pass or simple
                codecContext.YData = enTile.YEncodedData;
                codecContext.CbData = enTile.CbEncodedData;
                codecContext.CrData = enTile.CrEncodedData;
                RemoteFXDecoder.RLGRDecode(codecContext);
                ComputeOriginalLL3FromDeltas(codecContext);
            }
            else
            {
                SRLDecode(codecContext, enTile, tState);
            }

            //Progressive Dequantization
            if (enTile.DataType != EncodedTileType.Simple)
            {
                ProgressiveDeQuantization(codecContext, enTile.ProgCodecQuant);
            }

            // Create a DwtTile instance for tri-state
            DwtTile triStateDwt = new DwtTile(codecContext.YComponent, codecContext.CbComponent, codecContext.CrComponent,
                enTile.CodecQuantVals, enTile.QuantIdxY, enTile.QuantIdxCb, enTile.QuantIdxCr, enTile.UseReduceExtrapolate, enTile.ProgCodecQuant);

            //Set Tri-State for progressive codec
            if (enTile.DataType == EncodedTileType.FirstPass)
            {
                //DwtTile tileTriStat = SetTriState(diffDwt, enTile.UseReduceExtrapolate);
                tState.UpdateTriState(triStateDwt);
            }
            else if (enTile.DataType == EncodedTileType.UpgradePass)
            {
                DwtTile prvStat = tState.GetTriState();
                prvStat.Add(triStateDwt);
                // update ProCodecQuant
                prvStat.ProgCodecQuant = triStateDwt.ProgCodecQuant;
                tState.UpdateTriState(prvStat);
            }

            // Create another DwtTile instance for DWT Data.
            // 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
            DwtTile diffDwt = new DwtTile(codecContext.YComponent, codecContext.CbComponent, codecContext.CrComponent,
                enTile.CodecQuantVals, enTile.QuantIdxY, enTile.QuantIdxCb, enTile.QuantIdxCr, enTile.UseReduceExtrapolate, enTile.ProgCodecQuant);

            //Sum difference
            if ( enTile.IsDifferenceTile || enTile.DataType == EncodedTileType.UpgradePass)
            {
                tState.AddDwt(diffDwt);
            }
            else
            {
                tState.UpdateDwt(diffDwt);
            }
        }
        public static void SRLDecode(RfxProgressiveCodecContext codecContext, EncodedTile enTile, TileState tState)
        {
            SRLDecoder yDecoder = null;
            SRLDecoder cbDecoder = null;
            SRLDecoder crDecoder = null;

            List<short> yData = new List<short>();
            List<short> cbData = new List<short>();
            List<short> crData = new List<short>();
            DwtTile triState = tState.GetTriState();
            RFX_PROGRESSIVE_CODEC_QUANT prvProgQuant = tState.GetDwt().ProgCodecQuant;
            int nonLL3Len = RdpegfxTileUtils.ComponentElementCount - RdpegfxTileUtils.GetBandSize(BandType_Values.LL3, enTile.UseReduceExtrapolate);

            if (enTile.YEncodedData != null)
            {
                yDecoder = new SRLDecoder(enTile.YEncodedData);
            }

            if (enTile.CbEncodedData != null)
            {
                cbDecoder = new SRLDecoder(enTile.CbEncodedData);
            }

            if (enTile.CrEncodedData != null)
            {
                crDecoder = new SRLDecoder(enTile.CrEncodedData);
            }

            BitStream yRaw = BitStream.GetFromBytes(enTile.YRawData);
            BitStream cbRaw = BitStream.GetFromBytes(enTile.CbRawData);
            BitStream crRaw = BitStream.GetFromBytes(enTile.CrRawData);

            for (int i = 0; i < RdpegfxTileUtils.ComponentElementCount; i++)
            {
                BandType_Values band = RdpegfxTileUtils.GetBandByIndex(i, enTile.UseReduceExtrapolate);

                //Y
                int curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.yQuantValues, band);
                int prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.yQuantValues, band);
                int bitCount = prvBitPos - curBitPos;
                int sign = triState.Y_DwtQ[i];
                if (bitCount > 0)
                {
                    if (sign == 0 && i < nonLL3Len)
                    {
                        if (yDecoder != null)
                        {
                            short? decodedValue = yDecoder.DecodeOne(bitCount);
                            if (decodedValue.HasValue)
                            {
                                yData.Add(decodedValue.Value);
                            }
                            else
                            {
                                yData.Add(0);
                            }
                        }
                        else
                        {
                            yData.Add(0);
                        }
                    }
                    else
                    {
                        int output;
                        if (yRaw.ReadInt32(bitCount, out output))
                        {
                            if (sign < 0 && i < nonLL3Len) output = -output;
                            yData.Add((short)output);
                        }
                        else
                        {
                            yData.Add(0);
                        }
                    }
                }
                else
                {
                    yData.Add(0);
                }

                //Cb
                curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.cbQuantValues, band);
                prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.cbQuantValues, band);
                bitCount = prvBitPos - curBitPos;
                sign = triState.Cb_DwtQ[i];
                if (bitCount > 0)
                {
                    if (sign == 0 && i < nonLL3Len)
                    {
                        if (cbDecoder != null)
                        {
                            short? decodedValue = cbDecoder.DecodeOne(bitCount);
                            if (decodedValue.HasValue)
                            {
                                cbData.Add(decodedValue.Value);
                            }
                            else
                            {
                                cbData.Add(0);
                            }
                        }
                        else
                        {
                            cbData.Add(0);
                        }
                    }
                    else
                    {
                        int output;
                        if (cbRaw.ReadInt32(bitCount, out output))
                        {
                            if (sign < 0 && i < nonLL3Len) output = -output;
                            cbData.Add((short)output);
                        }
                        else
                        {
                            cbData.Add(0);
                        }
                    }
                }
                else
                {
                    cbData.Add(0);
                }

                //cr
                curBitPos = RdpegfxTileUtils.GetBitPosFromQuant(enTile.ProgCodecQuant.crQuantValues, band);
                prvBitPos = RdpegfxTileUtils.GetBitPosFromQuant(prvProgQuant.crQuantValues, band);
                bitCount = prvBitPos - curBitPos;
                sign = triState.Cr_DwtQ[i];
                if (bitCount > 0)
                {
                    if (sign == 0 && i < nonLL3Len)
                    {
                        if (crDecoder != null)
                        {
                            short? decodedValue = crDecoder.DecodeOne(bitCount);
                            if (decodedValue.HasValue)
                            {
                                crData.Add(decodedValue.Value);
                            }
                            else
                            {
                                crData.Add(0);
                            }
                        }
                        else
                        {
                            crData.Add(0);
                        }
                    }
                    else
                    {
                        int output;
                        if (crRaw.ReadInt32(bitCount, out output))
                        {
                            if (sign < 0 && i < nonLL3Len) output = -output;
                            crData.Add((short)output);
                        }
                        else
                        {
                            crData.Add(0);
                        }
                    }
                }
                else
                {
                    crData.Add(0);
                }
            }

            codecContext.YComponent = yData.ToArray();
            codecContext.CbComponent = cbData.ToArray();
            codecContext.CrComponent = crData.ToArray();
        }