/// <summary>
        /// Render progressive codec image
        /// </summary>
        /// <param name="surfaceId"></param>
        /// <param name="tileDict"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void RenderProgressiveCodec(ushort surfaceId, Dictionary <TileIndex, EncodedTile[]> tileDict, ushort width, ushort height)
        {
            if (surfaceDic.ContainsKey(surfaceId))
            {
                Bitmap   paint         = new Bitmap(width, height);
                Graphics paintGraphics = Graphics.FromImage(paint);
                if (surfaceDic[surfaceId].CurrentFrame == null)
                {
                    surfaceDic[surfaceId].CurrentFrame = new SurfaceFrame(surfaceId, width, height);
                }
                SurfaceFrame frame = surfaceDic[surfaceId].CurrentFrame;

                foreach (TileIndex index in tileDict.Keys)
                {
                    TileState     state = new TileState(frame, index);
                    EncodedTile[] tiles = tileDict[index];
                    if (tiles != null)
                    {
                        for (int i = 0; i < tiles.Length; i++)
                        {
                            RfxProgressiveDecoder.DecodeTile(tiles[i], state);
                        }
                    }
                    paintGraphics.DrawImage(state.GetDwt().ToImage(), index.X * RdpegfxTileUtils.TileSize, index.Y * RdpegfxTileUtils.TileSize);
                }

                Surface sur = surfaceDic[surfaceId];
                sur.DrawImage(paint, 0, 0);
            }
        }
        public static void SRLDecode(
            Triplet <byte[]> decodedData,
            Triplet <byte[]> rawData,
            QuantizationFactorsArray quant,
            Triplet <short[]> DAS,
            QuantizationFactorsArray preQuant,
            bool useReduceExtrapolate,
            out Triplet <short[]> output)
        {
            RFX_PROGRESSIVE_CODEC_QUANT progCodecQuant = Utility.ConvertProgQuant(quant);
            RFX_PROGRESSIVE_CODEC_QUANT preCodecQuant  = Utility.ConvertProgQuant(preQuant);
            // construct the fake parameter to invoke RfxProgressiveDecoder.SRLDecode
            var codecContext = new RfxProgressiveCodecContext(new[] { RdpegfxTileUtils.GetCodecQuant(ImageQuality_Values.Midium) }, 0, 0, 0, useReduceExtrapolate);
            var encodeTile   = new EncodedTile
            {
                YEncodedData         = decodedData.X,
                CbEncodedData        = decodedData.Y,
                CrEncodedData        = decodedData.Z,
                YRawData             = rawData.X,
                CbRawData            = rawData.Y,
                CrRawData            = rawData.Z,
                ProgCodecQuant       = progCodecQuant,
                UseReduceExtrapolate = useReduceExtrapolate // Important
            };
            var sentTile = new DwtTile(DAS.X, DAS.Y, DAS.Z);

            sentTile.ProgCodecQuant = preCodecQuant;
            var frame = new SurfaceFrame(0, RdpegfxTileUtils.TileSize, RdpegfxTileUtils.TileSize);

            frame.UpdateTileDwtQ(new TileIndex(0, 0, RdpegfxTileUtils.TileSize, RdpegfxTileUtils.TileSize), sentTile);
            frame.UpdateTriState(new TileIndex(0, 0, RdpegfxTileUtils.TileSize, RdpegfxTileUtils.TileSize), sentTile);
            var tileState = new TileState(frame, new TileIndex(0, 0, RdpegfxTileUtils.TileSize, RdpegfxTileUtils.TileSize));

            SRLDecode(codecContext, encodeTile, tileState);
            output = new Triplet <short[]>(codecContext.YComponent, codecContext.CbComponent, codecContext.CrComponent);
        }