/// <summary>
        /// Create region block.
        /// </summary>
        /// <param name="bReduceExtrapolate">This is used to indicate if DWT uses the "Reduce Extrapolate" method.</param>
        /// <param name="tileDict">This is used to indicate the dictionary of tile index and encoded data.</param>
        /// <param name="tileDataLength">This is used to indicate the encoded tile data length.</param>
        /// <param name="tileBlockType">This is used to indicate the tile data block type(simple, first, or upgrade).</param>
        public virtual RFX_Progressive_REGION BuildRegionBlock(bool bReduceExtrapolate, Dictionary<TileIndex, EncodedTile> TileDict, uint tileDataLength, RFXProgCodecBlockType tileBlockType)
        {
            // Create region block data.
            byte tfFlag = Convert.ToByte(bReduceExtrapolate);
            List<TS_RFX_RECT> tileRectList = new List<TS_RFX_RECT>();
            foreach (KeyValuePair<TileIndex, EncodedTile> tilePair in TileDict)
            {

                TS_RFX_RECT tileRect = new TS_RFX_RECT();
                tileRect.x = (ushort)(tilePair.Key.X * RFX_Progressive_CONST.CONTEXT_TILESIZE);
                tileRect.y = (ushort)(tilePair.Key.Y * RFX_Progressive_CONST.CONTEXT_TILESIZE);
                tileRect.width = tilePair.Key.WidthInSurface;
                tileRect.height = tilePair.Key.HeightInSurface;

                tileRectList.Add(tileRect);
            }
            TS_RFX_RECT[] tileRects = tileRectList.ToArray();
            EncodedTile[] tileDataArr = TileDict.Values.ToArray();

            bool bProg = (tileBlockType == RFXProgCodecBlockType.WBT_TILE_SIMPLE) ? false : true;

            RFX_Progressive_REGION region_block = new RFX_Progressive_REGION(bProg, tfFlag, tileDataLength, tileRects, tileDataArr);
            return region_block;
        }
        /// <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);
        }
 private bool IsInRects(int x, int y, TS_RFX_RECT[] rects)
 {
     if (rects != null && rects.Length > 0)
     {
         foreach (TS_RFX_RECT rect in rects)
         {
             if (IsInRect(x, y, rect))
             {
                 return true;
             }
         }
         return false;
     }
     return true;
 }
 private bool IsInRect(int x, int y, TS_RFX_RECT rect)
 {
     if (x >= rect.x && x < rect.x + rect.width && y >= rect.y && y < rect.y + rect.height)
         return true;
     return false;
 }