This class represents a subband in a bidirectional tree structure that describes the subband decomposition for a wavelet transform, specifically for the analysis side.

The element can be either a node or a leaf of the tree. If it is a node then ther are 4 descendants (LL, HL, LH and HH). If it is a leaf there are no descendants.

The tree is bidirectional. Each element in the tree structure has a "parent", which is the subband from which the element was obtained by decomposition. The only exception is the root element which has no parent (i.e.it's null), for obvious reasons.

상속: CSJ2K.j2k.wavelet.Subband
예제 #1
0
        /// <summary> Splits the current subband in its four subbands. It changes the status
        /// of this element (from a leaf to a node, and sets the filters), creates
        /// the childs and initializes them. An IllegalArgumentException is thrown
        /// if this subband is not a leaf.
        ///
        /// <p>It uses the initChilds() method to initialize the childs.</p>
        ///
        /// </summary>
        /// <param name="hfilter">The horizontal wavelet filter used to decompose this
        /// subband. It has to be a AnWTFilter object.
        ///
        /// </param>
        /// <param name="vfilter">The vertical wavelet filter used to decompose this
        /// subband. It has to be a AnWTFilter object.
        ///
        /// </param>
        /// <returns> A reference to the LL leaf (subb_LL).
        ///
        /// </returns>
        /// <seealso cref="Subband.initChilds">
        ///
        /// </seealso>
        protected internal override Subband split(WaveletFilter hfilter, WaveletFilter vfilter)
        {
            // Test that this is a node
            if (isNode)
            {
                throw new System.ArgumentException();
            }

            // Modify this element into a node and set the filters
            isNode       = true;
            this.hFilter = (AnWTFilter)hfilter;
            this.vFilter = (AnWTFilter)vfilter;

            // Create childs
            subb_LL = new SubbandAn();
            subb_LH = new SubbandAn();
            subb_HL = new SubbandAn();
            subb_HH = new SubbandAn();

            // Assign parent
            subb_LL.parentband = this;
            subb_HL.parentband = this;
            subb_LH.parentband = this;
            subb_HH.parentband = this;

            // Initialize childs
            initChilds();

            // Return reference to LL subband
            return(subb_LL);
        }
예제 #2
0
 /// <summary> Returns a reference to the subband tree structure representing the
 /// subband decomposition for the specified tile-component of the source.
 ///
 /// </summary>
 /// <param name="t">The index of the tile.
 ///
 /// </param>
 /// <param name="c">The index of the component.
 ///
 /// </param>
 /// <returns> The subband tree structure, see Subband.
 ///
 /// </returns>
 /// <seealso cref="SubbandAn">
 /// </seealso>
 /// <seealso cref="Subband">
 ///
 /// </seealso>
 public override SubbandAn getAnSubbandTree(int t, int c)
 {
     if (subbTrees[t][c] == null)
     {
         subbTrees[t][c] = new SubbandAn(getTileCompWidth(t, c), getTileCompHeight(t, c), getCompULX(c), getCompULY(c), getDecompLevels(t, c), getHorAnWaveletFilters(t, c), getVertAnWaveletFilters(t, c));
         initSubbandsFields(t, c, subbTrees[t][c]);
     }
     return(subbTrees[t][c]);
 }
예제 #3
0
        /// <summary> Performs the forward wavelet transform on the whole band. It
        /// iteratively decomposes the subbands from the top node to the leaves.
        ///
        /// </summary>
        /// <param name="band">The band containing the float data to decompose
        ///
        /// </param>
        /// <param name="subband">The structure containing the coordinates of the current
        /// subband in the whole band to decompose.
        ///
        /// </param>
        /// <param name="c">The index of the current component to decompose
        ///
        /// </param>
        private void waveletTreeDecomposition(DataBlk band, SubbandAn subband, int c)
        {
            //If the current subband is a leaf then nothing to be done (a leaf is
            //not decomposed).
            if (!subband.isNode)
            {
                return;
            }
            else
            {
                //Perform the 2D wavelet decomposition of the current subband
                wavelet2DDecomposition(band, (SubbandAn)subband, c);

                //Perform the decomposition of the four resulting subbands
                waveletTreeDecomposition(band, (SubbandAn)subband.HH, c);
                waveletTreeDecomposition(band, (SubbandAn)subband.LH, c);
                waveletTreeDecomposition(band, (SubbandAn)subband.HL, c);
                waveletTreeDecomposition(band, (SubbandAn)subband.LL, c);
            }
        }
예제 #4
0
        /// <summary> Initializes this object with the given source of image data and with
        /// all the decompositon parameters
        ///
        /// </summary>
        /// <param name="src">From where the image data should be obtained.
        ///
        /// </param>
        /// <param name="encSpec">The encoder specifications
        ///
        /// </param>
        /// <param name="cb0x">The horizontal coordinate of the code-block partition
        /// origin on the reference grid.
        ///
        /// </param>
        /// <param name="cb0y">The vertical coordinate of the code-block partition origin
        /// on the reference grid.
        ///
        /// </param>
        /// <seealso cref="ForwardWT">
        ///
        /// </seealso>
        public ForwWTFull(BlkImgDataSrc src, EncoderSpecs encSpec, int cb0x, int cb0y) : base(src)
        {
            this.src     = src;
            this.cb0x    = cb0x;
            this.cb0y    = cb0y;
            this.dls     = encSpec.dls;
            this.filters = encSpec.wfs;
            this.cblks   = encSpec.cblks;
            this.pss     = encSpec.pss;

            int ncomp  = src.NumComps;
            int ntiles = src.getNumTiles();

            currentSubband  = new SubbandAn[ncomp];
            decomposedComps = new DataBlk[ncomp];
            subbTrees       = new SubbandAn[ntiles][];
            for (int i = 0; i < ntiles; i++)
            {
                subbTrees[i] = new SubbandAn[ncomp];
            }
            lastn = new int[ncomp];
            lastm = new int[ncomp];
        }
예제 #5
0
        /// <summary> This function finds the new truncation points indices for a packet. It
        /// does so by including the data from the code-blocks in the component,
        /// resolution level and tile, associated with a R-D slope which is larger
        /// than or equal to 'fthresh'.
        /// 
        /// </summary>
        /// <param name="layerIdx">The index of the current layer
        /// 
        /// </param>
        /// <param name="compIdx">The index of the current component
        /// 
        /// </param>
        /// <param name="lvlIdx">The index of the current resolution level
        /// 
        /// </param>
        /// <param name="tileIdx">The index of the current tile
        /// 
        /// </param>
        /// <param name="subb">The LL subband in the resolution level lvlIdx, which is
        /// parent of all the subbands in the packet. Except for resolution level 0
        /// this subband is always a node.
        /// 
        /// </param>
        /// <param name="fthresh">The value of the rate-distortion threshold
        /// 
        /// </param>
        private void findTruncIndices(int layerIdx, int compIdx, int lvlIdx, int tileIdx, SubbandAn subb, float fthresh, int precinctIdx)
        {
            int minsbi, maxsbi, b, n; // bIdx removed
            //Coord ncblks = null;
            SubbandAn sb;
            CBlkRateDistStats cur_cblk;
            PrecInfo prec = pktEnc.getPrecInfo(tileIdx, compIdx, lvlIdx, precinctIdx);
            Coord cbCoord;

            sb = subb;
            while (sb.subb_HH != null)
            {
                sb = sb.subb_HH;
            }
            minsbi = (lvlIdx == 0)?0:1;
            maxsbi = (lvlIdx == 0)?1:4;

            int yend, xend;

            sb = (SubbandAn) subb.getSubbandByIdx(lvlIdx, minsbi);
            for (int s = minsbi; s < maxsbi; s++)
            {
                //loop on subbands
                yend = (prec.cblk[s] != null)?prec.cblk[s].Length:0;
                for (int y = 0; y < yend; y++)
                {
                    xend = (prec.cblk[s][y] != null)?prec.cblk[s][y].Length:0;
                    for (int x = 0; x < xend; x++)
                    {
                        cbCoord = prec.cblk[s][y][x].idx;
                        b = cbCoord.x + cbCoord.y * sb.numCb.x;

                        //Get the current code-block
                        cur_cblk = cblks[tileIdx][compIdx][lvlIdx][s][b];
                        for (n = 0; n < cur_cblk.nVldTrunc; n++)
                        {
                            if (cur_cblk.truncSlopes[n] < fthresh)
                            {
                                break;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        // Store the index in the code-block truncIdxs that gives
                        // the real truncation index.
                        truncIdxs[tileIdx][layerIdx][compIdx][lvlIdx][s][b] = n - 1;
                    } // End loop on horizontal code-blocks
                } // End loop on vertical code-blocks
                sb = (SubbandAn) sb.nextSubband();
            } // End loop on subbands
        }
예제 #6
0
파일: SubbandAn.cs 프로젝트: cureos/csj2k
        /// <summary> Splits the current subband in its four subbands. It changes the status
        /// of this element (from a leaf to a node, and sets the filters), creates
        /// the childs and initializes them. An IllegalArgumentException is thrown
        /// if this subband is not a leaf.
        /// 
        /// <p>It uses the initChilds() method to initialize the childs.</p>
        /// 
        /// </summary>
        /// <param name="hfilter">The horizontal wavelet filter used to decompose this
        /// subband. It has to be a AnWTFilter object.
        /// 
        /// </param>
        /// <param name="vfilter">The vertical wavelet filter used to decompose this
        /// subband. It has to be a AnWTFilter object.
        /// 
        /// </param>
        /// <returns> A reference to the LL leaf (subb_LL).
        /// 
        /// </returns>
        /// <seealso cref="Subband.initChilds">
        /// 
        /// </seealso>
        protected internal override Subband split(WaveletFilter hfilter, WaveletFilter vfilter)
        {
            // Test that this is a node
            if (isNode)
            {
                throw new System.ArgumentException();
            }

            // Modify this element into a node and set the filters
            isNode = true;
            this.hFilter = (AnWTFilter) hfilter;
            this.vFilter = (AnWTFilter) vfilter;

            // Create childs
            subb_LL = new SubbandAn();
            subb_LH = new SubbandAn();
            subb_HL = new SubbandAn();
            subb_HH = new SubbandAn();

            // Assign parent
            subb_LL.parentband = this;
            subb_HL.parentband = this;
            subb_LH.parentband = this;
            subb_HH.parentband = this;

            // Initialize childs
            initChilds();

            // Return reference to LL subband
            return subb_LL;
        }
예제 #7
0
		/// <summary> Performs the 2D forward wavelet transform on a subband of the initial
		/// band. This method will successively perform 1D filtering steps on all
		/// lines and then all columns of the subband. In this class only filters
		/// with floating point implementations can be used.
		/// 
		/// </summary>
		/// <param name="band">The band containing the float data to decompose
		/// 
		/// </param>
		/// <param name="subband">The structure containing the coordinates of the subband
		/// in the whole band to decompose.
		/// 
		/// </param>
		/// <param name="c">The index of the current component to decompose
		/// 
		/// </param>
		private void  wavelet2DDecomposition(DataBlk band, SubbandAn subband, int c)
		{
			
			int ulx, uly, w, h;
			int band_w, band_h;
			
			// If subband is empty (i.e. zero size) nothing to do
			if (subband.w == 0 || subband.h == 0)
			{
				return ;
			}
			
			ulx = subband.ulx;
			uly = subband.uly;
			w = subband.w;
			h = subband.h;
			band_w = getTileCompWidth(tIdx, c);
			band_h = getTileCompHeight(tIdx, c);
			
			if (intData)
			{
				//Perform the decompositions if the filter is implemented with an
				//integer arithmetic.
				int i, j;
				int offset;
				int[] tmpVector = new int[System.Math.Max(w, h)];
				int[] data = ((DataBlkInt) band).DataInt;
				
				//Perform the vertical decomposition
				if (subband.ulcy % 2 == 0)
				{
					// Even start index => use LPF
					for (j = 0; j < w; j++)
					{
						offset = uly * band_w + ulx + j;
						for (i = 0; i < h; i++)
							tmpVector[i] = data[offset + (i * band_w)];
						subband.vFilter.analyze_lpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + ((h + 1) / 2) * band_w, band_w);
					}
				}
				else
				{
					// Odd start index => use HPF
					for (j = 0; j < w; j++)
					{
						offset = uly * band_w + ulx + j;
						for (i = 0; i < h; i++)
							tmpVector[i] = data[offset + (i * band_w)];
						subband.vFilter.analyze_hpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + (h / 2) * band_w, band_w);
					}
				}
				
				//Perform the horizontal decomposition.
				if (subband.ulcx % 2 == 0)
				{
					// Even start index => use LPF
					for (i = 0; i < h; i++)
					{
						offset = (uly + i) * band_w + ulx;
						for (j = 0; j < w; j++)
							tmpVector[j] = data[offset + j];
						subband.hFilter.analyze_lpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + (w + 1) / 2, 1);
					}
				}
				else
				{
					// Odd start index => use HPF
					for (i = 0; i < h; i++)
					{
						offset = (uly + i) * band_w + ulx;
						for (j = 0; j < w; j++)
							tmpVector[j] = data[offset + j];
						subband.hFilter.analyze_hpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + w / 2, 1);
					}
				}
			}
			else
			{
				//Perform the decompositions if the filter is implemented with a
				//float arithmetic.
				int i, j;
				int offset;
				float[] tmpVector = new float[System.Math.Max(w, h)];
				float[] data = ((DataBlkFloat) band).DataFloat;
				
				//Perform the vertical decomposition.
				if (subband.ulcy % 2 == 0)
				{
					// Even start index => use LPF
					for (j = 0; j < w; j++)
					{
						offset = uly * band_w + ulx + j;
						for (i = 0; i < h; i++)
							tmpVector[i] = data[offset + (i * band_w)];
						subband.vFilter.analyze_lpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + ((h + 1) / 2) * band_w, band_w);
					}
				}
				else
				{
					// Odd start index => use HPF
					for (j = 0; j < w; j++)
					{
						offset = uly * band_w + ulx + j;
						for (i = 0; i < h; i++)
							tmpVector[i] = data[offset + (i * band_w)];
						subband.vFilter.analyze_hpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + (h / 2) * band_w, band_w);
					}
				}
				//Perform the horizontal decomposition.
				if (subband.ulcx % 2 == 0)
				{
					// Even start index => use LPF
					for (i = 0; i < h; i++)
					{
						offset = (uly + i) * band_w + ulx;
						for (j = 0; j < w; j++)
							tmpVector[j] = data[offset + j];
						subband.hFilter.analyze_lpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + (w + 1) / 2, 1);
					}
				}
				else
				{
					// Odd start index => use HPF
					for (i = 0; i < h; i++)
					{
						offset = (uly + i) * band_w + ulx;
						for (j = 0; j < w; j++)
							tmpVector[j] = data[offset + j];
						subband.hFilter.analyze_hpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + w / 2, 1);
					}
				}
			}
		}
예제 #8
0
		/// <summary> Performs the forward wavelet transform on the whole band. It
		/// iteratively decomposes the subbands from the top node to the leaves.
		/// 
		/// </summary>
		/// <param name="band">The band containing the float data to decompose
		/// 
		/// </param>
		/// <param name="subband">The structure containing the coordinates of the current
		/// subband in the whole band to decompose.
		/// 
		/// </param>
		/// <param name="c">The index of the current component to decompose
		/// 
		/// </param>
		private void  waveletTreeDecomposition(DataBlk band, SubbandAn subband, int c)
		{
			
			//If the current subband is a leaf then nothing to be done (a leaf is
			//not decomposed).
			if (!subband.isNode)
			{
				return ;
			}
			else
			{
				//Perform the 2D wavelet decomposition of the current subband
				wavelet2DDecomposition(band, (SubbandAn) subband, c);
				
				//Perform the decomposition of the four resulting subbands
				waveletTreeDecomposition(band, (SubbandAn) subband.HH, c);
				waveletTreeDecomposition(band, (SubbandAn) subband.LH, c);
				waveletTreeDecomposition(band, (SubbandAn) subband.HL, c);
				waveletTreeDecomposition(band, (SubbandAn) subband.LL, c);
			}
		}
예제 #9
0
		/// <summary> Initializes this object with the given source of image data and with
		/// all the decompositon parameters
		/// 
		/// </summary>
		/// <param name="src">From where the image data should be obtained.
		/// 
		/// </param>
		/// <param name="encSpec">The encoder specifications
		/// 
		/// </param>
		/// <param name="cb0x">The horizontal coordinate of the code-block partition
		/// origin on the reference grid.
		/// 
		/// </param>
		/// <param name="cb0y">The vertical coordinate of the code-block partition origin
		/// on the reference grid.
		/// 
		/// </param>
		/// <seealso cref="ForwardWT">
		/// 
		/// </seealso>
		public ForwWTFull(BlkImgDataSrc src, EncoderSpecs encSpec, int cb0x, int cb0y):base(src)
		{
			this.src = src;
			this.cb0x = cb0x;
			this.cb0y = cb0y;
			this.dls = encSpec.dls;
			this.filters = encSpec.wfs;
			this.cblks = encSpec.cblks;
			this.pss = encSpec.pss;
			
			int ncomp = src.NumComps;
			int ntiles = src.getNumTiles();
			
			currentSubband = new SubbandAn[ncomp];
			decomposedComps = new DataBlk[ncomp];
			subbTrees = new SubbandAn[ntiles][];
			for (int i = 0; i < ntiles; i++)
			{
				subbTrees[i] = new SubbandAn[ncomp];
			}
			lastn = new int[ncomp];
			lastm = new int[ncomp];
		}
예제 #10
0
		/// <summary> Returns a reference to the subband tree structure representing the
		/// subband decomposition for the specified tile-component of the source.
		/// 
		/// </summary>
		/// <param name="t">The index of the tile. 
		/// 
		/// </param>
		/// <param name="c">The index of the component. 
		/// 
		/// </param>
		/// <returns> The subband tree structure, see Subband. 
		/// 
		/// </returns>
		/// <seealso cref="SubbandAn">
		/// </seealso>
		/// <seealso cref="Subband">
		/// 
		/// </seealso>
		public override SubbandAn getAnSubbandTree(int t, int c)
		{
			if (subbTrees[t][c] == null)
			{
				subbTrees[t][c] = new SubbandAn(getTileCompWidth(t, c), getTileCompHeight(t, c), getCompULX(c), getCompULY(c), getDecompLevels(t, c), getHorAnWaveletFilters(t, c), getVertAnWaveletFilters(t, c));
				initSubbandsFields(t, c, subbTrees[t][c]);
			}
			return subbTrees[t][c];
		}
예제 #11
0
		/// <summary> Calculates the parameters of the SubbandAn objects that depend on the
		/// Quantizer. The 'stepWMSE' field is calculated for each subband which is
		/// a leaf in the tree rooted at 'sb', for the specified component. The
		/// subband tree 'sb' must be the one for the component 'n'.
		/// 
		/// </summary>
		/// <param name="sb">The root of the subband tree.
		/// 
		/// </param>
		/// <param name="n">The component index.
		/// 
		/// </param>
		/// <seealso cref="SubbandAn.stepWMSE">
		/// 
		/// </seealso>
		protected internal abstract void  calcSbParams(SubbandAn sb, int n);
예제 #12
0
		/// <summary> Calculates the parameters of the SubbandAn objects that depend on the
		/// Quantizer. The 'stepWMSE' field is calculated for each subband which is
		/// a leaf in the tree rooted at 'sb', for the specified component. The
		/// subband tree 'sb' must be the one for the component 'n'.
		/// 
		/// </summary>
		/// <param name="sb">The root of the subband tree.
		/// 
		/// </param>
		/// <param name="c">The component index
		/// 
		/// </param>
		/// <seealso cref="SubbandAn.stepWMSE">
		/// 
		/// </seealso>
		protected internal override void  calcSbParams(SubbandAn sb, int c)
		{
			float baseStep;
			
			if (sb.stepWMSE > 0f)
			// parameters already calculated
				return ;
			if (!sb.isNode)
			{
				if (isReversible(tIdx, c))
				{
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					sb.stepWMSE = (float) System.Math.Pow(2, - (src.getNomRangeBits(c) << 1)) * sb.l2Norm * sb.l2Norm;
				}
				else
				{
					//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
					baseStep = (float) ((System.Single) qsss.getTileCompVal(tIdx, c));
					if (isDerived(tIdx, c))
					{
						//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
						sb.stepWMSE = baseStep * baseStep * (float) System.Math.Pow(2, (sb.anGainExp - sb.level) << 1) * sb.l2Norm * sb.l2Norm;
					}
					else
					{
						sb.stepWMSE = baseStep * baseStep;
					}
				}
			}
			else
			{
				calcSbParams((SubbandAn) sb.LL, c);
				calcSbParams((SubbandAn) sb.HL, c);
				calcSbParams((SubbandAn) sb.LH, c);
				calcSbParams((SubbandAn) sb.HH, c);
				sb.stepWMSE = 1f; // Signal that we already calculated this branch
			}
		}
예제 #13
0
        /// <summary> Performs the 2D forward wavelet transform on a subband of the initial
        /// band. This method will successively perform 1D filtering steps on all
        /// lines and then all columns of the subband. In this class only filters
        /// with floating point implementations can be used.
        ///
        /// </summary>
        /// <param name="band">The band containing the float data to decompose
        ///
        /// </param>
        /// <param name="subband">The structure containing the coordinates of the subband
        /// in the whole band to decompose.
        ///
        /// </param>
        /// <param name="c">The index of the current component to decompose
        ///
        /// </param>
        private void wavelet2DDecomposition(DataBlk band, SubbandAn subband, int c)
        {
            int ulx, uly, w, h;
            int band_w, band_h;

            // If subband is empty (i.e. zero size) nothing to do
            if (subband.w == 0 || subband.h == 0)
            {
                return;
            }

            ulx    = subband.ulx;
            uly    = subband.uly;
            w      = subband.w;
            h      = subband.h;
            band_w = getTileCompWidth(tIdx, c);
            band_h = getTileCompHeight(tIdx, c);

            if (intData)
            {
                //Perform the decompositions if the filter is implemented with an
                //integer arithmetic.
                int   i, j;
                int   offset;
                int[] tmpVector = new int[System.Math.Max(w, h)];
                int[] data      = ((DataBlkInt)band).DataInt;

                //Perform the vertical decomposition
                if (subband.ulcy % 2 == 0)
                {
                    // Even start index => use LPF
                    for (j = 0; j < w; j++)
                    {
                        offset = uly * band_w + ulx + j;
                        for (i = 0; i < h; i++)
                        {
                            tmpVector[i] = data[offset + (i * band_w)];
                        }
                        subband.vFilter.analyze_lpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + ((h + 1) / 2) * band_w, band_w);
                    }
                }
                else
                {
                    // Odd start index => use HPF
                    for (j = 0; j < w; j++)
                    {
                        offset = uly * band_w + ulx + j;
                        for (i = 0; i < h; i++)
                        {
                            tmpVector[i] = data[offset + (i * band_w)];
                        }
                        subband.vFilter.analyze_hpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + (h / 2) * band_w, band_w);
                    }
                }

                //Perform the horizontal decomposition.
                if (subband.ulcx % 2 == 0)
                {
                    // Even start index => use LPF
                    for (i = 0; i < h; i++)
                    {
                        offset = (uly + i) * band_w + ulx;
                        for (j = 0; j < w; j++)
                        {
                            tmpVector[j] = data[offset + j];
                        }
                        subband.hFilter.analyze_lpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + (w + 1) / 2, 1);
                    }
                }
                else
                {
                    // Odd start index => use HPF
                    for (i = 0; i < h; i++)
                    {
                        offset = (uly + i) * band_w + ulx;
                        for (j = 0; j < w; j++)
                        {
                            tmpVector[j] = data[offset + j];
                        }
                        subband.hFilter.analyze_hpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + w / 2, 1);
                    }
                }
            }
            else
            {
                //Perform the decompositions if the filter is implemented with a
                //float arithmetic.
                int     i, j;
                int     offset;
                float[] tmpVector = new float[System.Math.Max(w, h)];
                float[] data      = ((DataBlkFloat)band).DataFloat;

                //Perform the vertical decomposition.
                if (subband.ulcy % 2 == 0)
                {
                    // Even start index => use LPF
                    for (j = 0; j < w; j++)
                    {
                        offset = uly * band_w + ulx + j;
                        for (i = 0; i < h; i++)
                        {
                            tmpVector[i] = data[offset + (i * band_w)];
                        }
                        subband.vFilter.analyze_lpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + ((h + 1) / 2) * band_w, band_w);
                    }
                }
                else
                {
                    // Odd start index => use HPF
                    for (j = 0; j < w; j++)
                    {
                        offset = uly * band_w + ulx + j;
                        for (i = 0; i < h; i++)
                        {
                            tmpVector[i] = data[offset + (i * band_w)];
                        }
                        subband.vFilter.analyze_hpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + (h / 2) * band_w, band_w);
                    }
                }
                //Perform the horizontal decomposition.
                if (subband.ulcx % 2 == 0)
                {
                    // Even start index => use LPF
                    for (i = 0; i < h; i++)
                    {
                        offset = (uly + i) * band_w + ulx;
                        for (j = 0; j < w; j++)
                        {
                            tmpVector[j] = data[offset + j];
                        }
                        subband.hFilter.analyze_lpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + (w + 1) / 2, 1);
                    }
                }
                else
                {
                    // Odd start index => use HPF
                    for (i = 0; i < h; i++)
                    {
                        offset = (uly + i) * band_w + ulx;
                        for (j = 0; j < w; j++)
                        {
                            tmpVector[j] = data[offset + j];
                        }
                        subband.hFilter.analyze_hpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + w / 2, 1);
                    }
                }
            }
        }