Exemple #1
0
 /// <summary> Creates the top-level node and the entire subband tree, with the
 /// top-level dimensions, the number of decompositions, and the
 /// decomposition tree as specified.
 /// 
 /// <p>This constructor just calls the same constructor of the super class,
 /// and then calculates the L2-norm (or energy weight) of each leaf.</p>
 /// 
 /// <p>This constructor does not initialize the value of the magBits or
 /// stepWMSE member variables. This variables are normally initialized by
 /// the quantizer (see Quantizer).</p>
 /// 
 /// </summary>
 /// <param name="w">The top-level width
 /// 
 /// </param>
 /// <param name="h">The top-level height
 /// 
 /// </param>
 /// <param name="ulcx">The horizontal coordinate of the upper-left corner with
 /// respect to the canvas origin, in the component grid.
 /// 
 /// </param>
 /// <param name="ulcy">The vertical coordinate of the upper-left corner with
 /// respect to the canvas origin, in the component grid.
 /// 
 /// </param>
 /// <param name="lvls">The number of levels (or LL decompositions) in the tree.
 /// 
 /// </param>
 /// <param name="hfilters">The horizontal wavelet analysis filters for each
 /// resolution level, starting at resolution level 0.
 /// 
 /// </param>
 /// <param name="vfilters">The vertical wavelet analysis filters for each
 /// resolution level, starting at resolution level 0.
 /// 
 /// </param>
 /// <seealso cref="Subband.Subband(int,int,int,int,int,">
 /// WaveletFilter[],WaveletFilter[])
 /// 
 /// </seealso>
 /// <seealso cref="jj2000.j2k.quantization.quantizer.Quantizer">
 /// 
 /// </seealso>
 public SubbandAn(int w, int h, int ulcx, int ulcy, int lvls, WaveletFilter[] hfilters, WaveletFilter[] vfilters)
     : base(w, h, ulcx, ulcy, lvls, hfilters, vfilters)
 {
     // Caculate the L2-norms
     calcL2Norms();
 }
Exemple #2
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;
        }
        /// <summary> This function decomposes the mask for a node in the subband tree.
        /// after the mask is decomposed for a node, this function is called for
        /// the children of the subband. The decomposition is done line by line
        /// and column by column
        ///
        /// </summary>
        /// <param name="sb">The subband that is to be used for the decomposition
        ///
        /// </param>
        /// <param name="tilew">The width of the current tile
        ///
        /// </param>
        /// <param name="tileh">The height of the current tile
        ///
        /// </param>
        /// <param name="c">component number
        /// </param>
        private void  decomp(Subband sb, int tilew, int tileh, int c)
        {
            int ulx = sb.ulx;
            int uly = sb.uly;
            int w = sb.w;
            int h = sb.h;
            int scalVal, maxVal = 0;
            int j, k, s, mi = 0, pin;         // i, hi, li removed
            int hmax, lmax;                   // smax removed
            int lineoffs;                     // wrap, lastlow removed

            int[] mask      = roiMask[c];     // local copy
            int[] low       = maskLineLow;    // local copy
            int[] high      = maskLineHigh;   // local copy
            int[] padLine   = paddedMaskLine; // local copy
            int   highFirst = 0;
            int   lastpin;


            if (!sb.isNode)
            {
                return;
            }

            // HORIZONTAL DECOMPOSITION

            // Calculate number of high and low samples after decomposition
            // and get support for low and high filters
            WaveletFilter filter = sb.HorWFilter;
            int           lnSup  = filter.SynLowNegSupport;
            int           hnSup  = filter.SynHighNegSupport;
            int           lpSup  = filter.SynLowPosSupport;
            int           hpSup  = filter.SynHighPosSupport;
            int           lsup   = lnSup + lpSup + 1;
            int           hsup   = hnSup + hpSup + 1;

            // Calculate number of high/low coeffis in subbands
            highFirst = sb.ulcx % 2;
            if (sb.w % 2 == 0)
            {
                lmax = w / 2 - 1;
                hmax = lmax;
            }
            else
            {
                if (highFirst == 0)
                {
                    lmax = (w + 1) / 2 - 1;
                    hmax = w / 2 - 1;
                }
                else
                {
                    hmax = (w + 1) / 2 - 1;
                    lmax = w / 2 - 1;
                }
            }

            int maxnSup = (lnSup > hnSup)?lnSup:hnSup;             // Maximum negative support
            int maxpSup = (lpSup > hpSup)?lpSup:hpSup;             // Maximum positive support


            // Set padding to 0
            for (pin = maxnSup - 1; pin >= 0; pin--)
            {
                padLine[pin] = 0;
            }
            for (pin = maxnSup + w - 1 + maxpSup; pin >= w; pin--)
            {
                padLine[pin] = 0;
            }

            // Do decomposition of all lines
            lineoffs = (uly + h) * tilew + ulx + w - 1;
            for (j = h - 1; j >= 0; j--)
            {
                lineoffs -= tilew;
                // Get the line to transform from the mask
                mi = lineoffs;
                for (k = w, pin = w - 1 + maxnSup; k > 0; k--, mi--, pin--)
                {
                    padLine[pin] = mask[mi];
                }

                lastpin = maxnSup + highFirst + 2 * lmax + lpSup;
                for (k = lmax; k >= 0; k--, lastpin -= 2)
                {
                    // Low frequency samples
                    pin = lastpin;
                    for (s = lsup; s > 0; s--, pin--)
                    {
                        scalVal = padLine[pin];
                        if (scalVal > maxVal)
                        {
                            maxVal = scalVal;
                        }
                    }
                    low[k] = maxVal;
                    maxVal = 0;
                }
                lastpin = maxnSup - highFirst + 2 * hmax + 1 + hpSup;
                for (k = hmax; k >= 0; k--, lastpin -= 2)
                {
                    // High frequency samples
                    pin = lastpin;
                    for (s = hsup; s > 0; s--, pin--)
                    {
                        scalVal = padLine[pin];
                        if (scalVal > maxVal)
                        {
                            maxVal = scalVal;
                        }
                    }
                    high[k] = maxVal;
                    maxVal  = 0;
                }
                // Put the lows and highs back
                mi = lineoffs;
                for (k = hmax; k >= 0; k--, mi--)
                {
                    mask[mi] = high[k];
                }
                for (k = lmax; k >= 0; k--, mi--)
                {
                    mask[mi] = low[k];
                }
            }

            // VERTICAL DECOMPOSITION

            // Calculate number of high and low samples after decomposition
            // and get support for low and high filters
            filter = sb.VerWFilter;
            lnSup  = filter.SynLowNegSupport;
            hnSup  = filter.SynHighNegSupport;
            lpSup  = filter.SynLowPosSupport;
            hpSup  = filter.SynHighPosSupport;
            lsup   = lnSup + lpSup + 1;
            hsup   = hnSup + hpSup + 1;

            // Calculate number of high/low coeffs in subbands
            highFirst = sb.ulcy % 2;
            if (sb.h % 2 == 0)
            {
                lmax = h / 2 - 1;
                hmax = lmax;
            }
            else
            {
                if (sb.ulcy % 2 == 0)
                {
                    lmax = (h + 1) / 2 - 1;
                    hmax = h / 2 - 1;
                }
                else
                {
                    hmax = (h + 1) / 2 - 1;
                    lmax = h / 2 - 1;
                }
            }

            maxnSup = (lnSup > hnSup)?lnSup:hnSup;             // Maximum negative support
            maxpSup = (lpSup > hpSup)?lpSup:hpSup;             // Maximum positive support

            // Set padding to 0
            for (pin = maxnSup - 1; pin >= 0; pin--)
            {
                padLine[pin] = 0;
            }
            for (pin = maxnSup + h - 1 + maxpSup; pin >= h; pin--)
            {
                padLine[pin] = 0;
            }

            // Do decomposition of all columns
            lineoffs = (uly + h - 1) * tilew + ulx + w;
            for (j = w - 1; j >= 0; j--)
            {
                lineoffs--;
                // Get the line to transform from the mask
                mi = lineoffs;
                for (k = h, pin = k - 1 + maxnSup; k > 0; k--, mi -= tilew, pin--)
                {
                    padLine[pin] = mask[mi];
                }
                lastpin = maxnSup + highFirst + 2 * lmax + lpSup;
                for (k = lmax; k >= 0; k--, lastpin -= 2)
                {
                    // Low frequency samples
                    pin = lastpin;
                    for (s = lsup; s > 0; s--, pin--)
                    {
                        scalVal = padLine[pin];
                        if (scalVal > maxVal)
                        {
                            maxVal = scalVal;
                        }
                    }
                    low[k] = maxVal;
                    maxVal = 0;
                }
                lastpin = maxnSup - highFirst + 2 * hmax + 1 + hpSup;
                for (k = hmax; k >= 0; k--, lastpin -= 2)
                {
                    // High frequency samples
                    pin = lastpin;
                    for (s = hsup; s > 0; s--, pin--)
                    {
                        scalVal = padLine[pin];
                        if (scalVal > maxVal)
                        {
                            maxVal = scalVal;
                        }
                    }
                    high[k] = maxVal;
                    maxVal  = 0;
                }
                // Put the lows and highs back
                mi = lineoffs;
                for (k = hmax; k >= 0; k--, mi -= tilew)
                {
                    mask[mi] = high[k];
                }
                for (k = lmax; k >= 0; k--, mi -= tilew)
                {
                    mask[mi] = low[k];
                }
            }

            if (sb.isNode)
            {
                decomp(sb.HH, tilew, tileh, c);
                decomp(sb.LH, tilew, tileh, c);
                decomp(sb.HL, tilew, tileh, c);
                decomp(sb.LL, tilew, tileh, c);
            }
        }
Exemple #4
0
		/// <summary> Creates the top-level node and the entire subband tree, with the
		/// top-level dimensions, the number of decompositions, and the
		/// decomposition tree as specified.
		/// 
		/// <p>This constructor just calls the same constructor of the super
		/// class.</p>
		/// 
		/// </summary>
		/// <param name="w">The top-level width
		/// 
		/// </param>
		/// <param name="h">The top-level height
		/// 
		/// </param>
		/// <param name="ulcx">The horizontal coordinate of the upper-left corner with
		/// respect to the canvas origin, in the component grid.
		/// 
		/// </param>
		/// <param name="ulcy">The vertical coordinate of the upper-left corner with
		/// respect to the canvas origin, in the component grid.
		/// 
		/// </param>
		/// <param name="lvls">The number of levels (or LL decompositions) in the tree.
		/// 
		/// </param>
		/// <param name="hfilters">The horizontal wavelet synthesis filters for each
		/// resolution level, starting at resolution level 0.
		/// 
		/// </param>
		/// <param name="vfilters">The vertical wavelet synthesis filters for each
		/// resolution level, starting at resolution level 0.
		/// 
		/// </param>
		/// <seealso cref="Subband.Subband(int,int,int,int,int,">
		/// WaveletFilter[],WaveletFilter[])
		/// 
		/// </seealso>
		public SubbandSyn(int w, int h, int ulcx, int ulcy, int lvls, WaveletFilter[] hfilters, WaveletFilter[] vfilters):base(w, h, ulcx, ulcy, lvls, hfilters, vfilters)
		{
		}
        /// <summary> This function generates the ROI mask for one tile-component.
        ///
        /// <P> Once the mask is generated in the pixel domain. it is decomposed
        /// following the same decomposition scheme as the wavelet transform.
        ///
        /// </summary>
        /// <param name="sb">The root of the subband tree used in the decomposition
        ///
        /// </param>
        /// <param name="magbits">The max number of magnitude bits in any code-block
        ///
        /// </param>
        /// <param name="c">component number
        /// </param>
        public override void  makeMask(Subband sb, int magbits, int c)
        {
            int[] mask;                  // local copy
            ROI[] rois = this.roi_array; // local copy
            int   i, j, k, r, maxj;      // mink, minj removed
            int   lrx, lry;
            int   x, y, w, h;
            int   cx, cy, rad;
            int   wrap;
            int   curScalVal;
            int   tileulx = sb.ulcx;
            int   tileuly = sb.ulcy;
            int   tilew   = sb.w;
            int   tileh   = sb.h;
            int   lineLen = (tilew > tileh)?tilew:tileh;

            // Make sure there is a sufficiently large mask buffer
            if (roiMask[c] == null || (roiMask[c].Length < (tilew * tileh)))
            {
                roiMask[c] = new int[tilew * tileh];
                mask       = roiMask[c];
            }
            else
            {
                mask = roiMask[c];
                for (i = tilew * tileh - 1; i >= 0; i--)
                {
                    mask[i] = 0;
                }
            }

            // Make sure there are sufficiently large line buffers
            if (maskLineLow == null || (maskLineLow.Length < (lineLen + 1) / 2))
            {
                maskLineLow = new int[(lineLen + 1) / 2];
            }
            if (maskLineHigh == null || (maskLineHigh.Length < (lineLen + 1) / 2))
            {
                maskLineHigh = new int[(lineLen + 1) / 2];
            }

            roiInTile = false;
            // Generate ROIs in pixel domain:
            for (r = rois.Length - 1; r >= 0; r--)
            {
                if (rois[r].comp == c)
                {
                    curScalVal = magbits;

                    if (rois[r].arbShape)
                    {
                        ImgReaderPGM maskPGM = rois[r].maskPGM;                         // Local copy

                        if ((src.ImgWidth != maskPGM.ImgWidth) || (src.ImgHeight != maskPGM.ImgHeight))
                        {
                            throw new System.ArgumentException("Input image and" + " ROI mask must " + "have the same " + "size");
                        }
                        x   = src.ImgULX;
                        y   = src.ImgULY;
                        lrx = x + src.ImgWidth - 1;
                        lry = y + src.ImgHeight - 1;
                        if ((x > tileulx + tilew) || (y > tileuly + tileh) || (lrx < tileulx) || (lry < tileuly))
                        {
                            // Roi not in tile
                            continue;
                        }

                        // Check bounds
                        x   -= tileulx;
                        lrx -= tileulx;
                        y   -= tileuly;
                        lry -= tileuly;

                        int offx = 0;
                        int offy = 0;
                        if (x < 0)
                        {
                            offx = -x;
                            x    = 0;
                        }
                        if (y < 0)
                        {
                            offy = -y;
                            y    = 0;
                        }
                        w = (lrx > (tilew - 1))?tilew - x:lrx + 1 - x;
                        h = (lry > (tileh - 1))?tileh - y:lry + 1 - y;


                        // Get shape line by line to reduce memory
                        DataBlkInt srcblk    = new DataBlkInt();
                        int        mDcOff    = -ImgReaderPGM.DC_OFFSET;
                        int        nROIcoeff = 0;
                        int[]      src_data;
                        srcblk.ulx = offx;
                        srcblk.w   = w;
                        srcblk.h   = 1;

                        i    = (y + h - 1) * tilew + x + w - 1;
                        maxj = w;
                        wrap = tilew - maxj;
                        for (k = h; k > 0; k--)
                        {
                            srcblk.uly = offy + k - 1;
                            srcblk     = (DataBlkInt)maskPGM.getInternCompData(srcblk, 0);
                            src_data   = srcblk.DataInt;

                            for (j = maxj; j > 0; j--, i--)
                            {
                                if (src_data[j - 1] != mDcOff)
                                {
                                    mask[i] = curScalVal;
                                    nROIcoeff++;
                                }
                            }
                            i -= wrap;
                        }

                        if (nROIcoeff != 0)
                        {
                            roiInTile = true;
                        }
                    }
                    else if (rois[r].rect)
                    {
                        // Rectangular ROI
                        x   = rois[r].ulx;
                        y   = rois[r].uly;
                        lrx = rois[r].w + x - 1;
                        lry = rois[r].h + y - 1;

                        if ((x > tileulx + tilew) || (y > tileuly + tileh) || (lrx < tileulx) || (lry < tileuly))
                        {
                            // Roi not in tile
                            continue;
                        }

                        roiInTile = true;

                        // Check bounds
                        x   -= tileulx;
                        lrx -= tileulx;
                        y   -= tileuly;
                        lry -= tileuly;

                        x = (x < 0)?0:x;
                        y = (y < 0)?0:y;
                        w = (lrx > (tilew - 1))?tilew - x:lrx + 1 - x;
                        h = (lry > (tileh - 1))?tileh - y:lry + 1 - y;

                        i    = (y + h - 1) * tilew + x + w - 1;
                        maxj = w;
                        wrap = tilew - maxj;
                        for (k = h; k > 0; k--)
                        {
                            for (j = maxj; j > 0; j--, i--)
                            {
                                mask[i] = curScalVal;
                            }
                            i -= wrap;
                        }
                    }
                    else
                    {
                        // Non-rectangular ROI. So far only circular case
                        cx  = rois[r].x - tileulx;
                        cy  = rois[r].y - tileuly;
                        rad = rois[r].r;
                        i   = tileh * tilew - 1;
                        for (k = tileh - 1; k >= 0; k--)
                        {
                            for (j = tilew - 1; j >= 0; j--, i--)
                            {
                                if (((j - cx) * (j - cx) + (k - cy) * (k - cy) < rad * rad))
                                {
                                    mask[i]   = curScalVal;
                                    roiInTile = true;
                                }
                            }
                        }
                    }
                }
            }

            // If wavelet transform is used
            if (sb.isNode)
            {
                // Decompose the mask according to the subband tree
                // Calculate size of padded line buffer
                WaveletFilter vFilter = sb.VerWFilter;
                WaveletFilter hFilter = sb.HorWFilter;
                int           lvsup   = vFilter.SynLowNegSupport + vFilter.SynLowPosSupport;
                int           hvsup   = vFilter.SynHighNegSupport + vFilter.SynHighPosSupport;
                int           lhsup   = hFilter.SynLowNegSupport + hFilter.SynLowPosSupport;
                int           hhsup   = hFilter.SynHighNegSupport + hFilter.SynHighPosSupport;
                lvsup          = (lvsup > hvsup)?lvsup:hvsup;
                lhsup          = (lhsup > hhsup)?lhsup:hhsup;
                lvsup          = (lvsup > lhsup)?lvsup:lhsup;
                paddedMaskLine = new int[lineLen + lvsup];

                if (roiInTile)
                {
                    decomp(sb, tilew, tileh, c);
                }
            }
        }
Exemple #6
0
 /// <summary> Splits the current subband in its four subbands. This creates the four
 /// childs (LL, HL, LH and HH) and converts the leaf in a node.
 ///
 /// </summary>
 /// <param name="hfilter">The horizontal wavelet filter used to decompose this
 /// subband.
 ///
 /// </param>
 /// <param name="vfilter">The vertical wavelet filter used to decompose this
 /// subband.
 ///
 /// </param>
 /// <returns>  A reference to the LL leaf (getLL()).
 ///
 /// </returns>
 protected internal abstract Subband split(WaveletFilter hfilter, WaveletFilter vfilter);
        /// <summary> The constructor of the SubbandROIMask takes the dimensions of the
        /// subband as parameters. A tree of masks is generated from the subband
        /// sb. Each Subband contains the boundaries of each ROI.
        ///
        /// </summary>
        /// <param name="sb">The subband corresponding to this Subband Mask
        ///
        /// </param>
        /// <param name="ulxs">The upper left x coordinates of the ROIs
        ///
        /// </param>
        /// <param name="ulys">The upper left y coordinates of the ROIs
        ///
        /// </param>
        /// <param name="lrxs">The lower right x coordinates of the ROIs
        ///
        /// </param>
        /// <param name="lrys">The lower right y coordinates of the ROIs
        ///
        /// </param>
        /// <param name="lrys">The lower right y coordinates of the ROIs
        ///
        /// </param>
        /// <param name="nr">Number of ROIs that affect this tile
        ///
        /// </param>
        public SubbandRectROIMask(Subband sb, int[] ulxs, int[] ulys, int[] lrxs, int[] lrys, int nr) : base(sb.ulx, sb.uly, sb.w, sb.h)
        {
            this.ulxs = ulxs;
            this.ulys = ulys;
            this.lrxs = lrxs;
            this.lrys = lrys;
            int r;

            if (sb.isNode)
            {
                isNode = true;
                // determine odd/even - high/low filters
                int horEvenLow = sb.ulcx % 2;
                int verEvenLow = sb.ulcy % 2;

                // Get filter support lengths
                WaveletFilter hFilter = sb.HorWFilter;
                WaveletFilter vFilter = sb.VerWFilter;
                int           hlnSup  = hFilter.SynLowNegSupport;
                int           hhnSup  = hFilter.SynHighNegSupport;
                int           hlpSup  = hFilter.SynLowPosSupport;
                int           hhpSup  = hFilter.SynHighPosSupport;
                int           vlnSup  = vFilter.SynLowNegSupport;
                int           vhnSup  = vFilter.SynHighNegSupport;
                int           vlpSup  = vFilter.SynLowPosSupport;
                int           vhpSup  = vFilter.SynHighPosSupport;

                // Generate arrays for children
                int   x, y;
                int[] lulxs = new int[nr];
                int[] lulys = new int[nr];
                int[] llrxs = new int[nr];
                int[] llrys = new int[nr];
                int[] hulxs = new int[nr];
                int[] hulys = new int[nr];
                int[] hlrxs = new int[nr];
                int[] hlrys = new int[nr];
                for (r = nr - 1; r >= 0; r--)
                {
                    // For all ROI calculate ...
                    // Upper left x for all children
                    x = ulxs[r];
                    if (horEvenLow == 0)
                    {
                        lulxs[r] = (x + 1 - hlnSup) / 2;
                        hulxs[r] = (x - hhnSup) / 2;
                    }
                    else
                    {
                        lulxs[r] = (x - hlnSup) / 2;
                        hulxs[r] = (x + 1 - hhnSup) / 2;
                    }
                    // Upper left y for all children
                    y = ulys[r];
                    if (verEvenLow == 0)
                    {
                        lulys[r] = (y + 1 - vlnSup) / 2;
                        hulys[r] = (y - vhnSup) / 2;
                    }
                    else
                    {
                        lulys[r] = (y - vlnSup) / 2;
                        hulys[r] = (y + 1 - vhnSup) / 2;
                    }
                    // lower right x for all children
                    x = lrxs[r];
                    if (horEvenLow == 0)
                    {
                        llrxs[r] = (x + hlpSup) / 2;
                        hlrxs[r] = (x - 1 + hhpSup) / 2;
                    }
                    else
                    {
                        llrxs[r] = (x - 1 + hlpSup) / 2;
                        hlrxs[r] = (x + hhpSup) / 2;
                    }
                    // lower right y for all children
                    y = lrys[r];
                    if (verEvenLow == 0)
                    {
                        llrys[r] = (y + vlpSup) / 2;
                        hlrys[r] = (y - 1 + vhpSup) / 2;
                    }
                    else
                    {
                        llrys[r] = (y - 1 + vlpSup) / 2;
                        hlrys[r] = (y + vhpSup) / 2;
                    }
                }
                // Create children
                hh = new SubbandRectROIMask(sb.HH, hulxs, hulys, hlrxs, hlrys, nr);
                lh = new SubbandRectROIMask(sb.LH, lulxs, hulys, llrxs, hlrys, nr);
                hl = new SubbandRectROIMask(sb.HL, hulxs, lulys, hlrxs, llrys, nr);
                ll = new SubbandRectROIMask(sb.LL, lulxs, lulys, llrxs, llrys, nr);
            }
        }
Exemple #8
0
		/// <summary> Creates the top-level node and the entire subband tree, with the
		/// top-level dimensions, the number of decompositions, and the
		/// decomposition tree as specified.
		/// 
		/// <p>For the analysis subband gain calculation it is assumed that
		/// analysis filters are normalized with a DC gain of 1 and a Nyquist gain
		/// of 2.</p>
		/// 
		/// <p>This constructor does not initialize the value of the magBits member
		/// variable. This variable is normally initialized by the quantizer, on
		/// the encoder side, or the bit stream reader, on the decoder side.</p>
		/// 
		/// </summary>
		/// <param name="w">The top-level width
		/// 
		/// </param>
		/// <param name="h">The top-level height
		/// 
		/// </param>
		/// <param name="ulcx">The horizontal coordinate of the upper-left corner with
		/// respect to the canvas origin, in the component grid.
		/// 
		/// </param>
		/// <param name="ulcy">The vertical coordinate of the upper-left corner with
		/// respect to the canvas origin, in the component grid.
		/// 
		/// </param>
		/// <param name="lvls">The number of levels (or LL decompositions) in the tree.
		/// 
		/// </param>
		/// <param name="hfilters">The horizontal wavelet filters (analysis or synthesis)
		/// for each resolution level, starting at resolution level 0. If there are
		/// less elements in the array than there are resolution levels, the last
		/// element is used for the remaining resolution levels.
		/// 
		/// </param>
		/// <param name="vfilters">The vertical wavelet filters (analysis or synthesis)
		/// for each resolution level, starting at resolution level 0. If there are
		/// less elements in the array than there are resolution levels, the last
		/// element is used for the remaining resolution levels.
		/// 
		/// </param>
		/// <seealso cref="WaveletTransform">
		/// 
		/// </seealso>
		public Subband(int w, int h, int ulcx, int ulcy, int lvls, WaveletFilter[] hfilters, WaveletFilter[] vfilters)
		{
			int i, hi, vi;
			Subband cur; // The current subband
			
			// Initialize top-level node
			this.w = w;
			this.h = h;
			this.ulcx = ulcx;
			this.ulcy = ulcy;
			this.resLvl = lvls;
			// First create dyadic decomposition.
			cur = this;
			for (i = 0; i < lvls; i++)
			{
				hi = (cur.resLvl <= hfilters.Length)?cur.resLvl - 1:hfilters.Length - 1;
				vi = (cur.resLvl <= vfilters.Length)?cur.resLvl - 1:vfilters.Length - 1;
				cur = cur.split(hfilters[hi], vfilters[vi]);
			}
		}
Exemple #9
0
		/// <summary> Splits the current subband in its four subbands. This creates the four
		/// childs (LL, HL, LH and HH) and converts the leaf in a node.
		/// 
		/// </summary>
		/// <param name="hfilter">The horizontal wavelet filter used to decompose this
		/// subband.
		/// 
		/// </param>
		/// <param name="vfilter">The vertical wavelet filter used to decompose this
		/// subband.
		/// 
		/// </param>
		/// <returns>  A reference to the LL leaf (getLL()).
		/// 
		/// </returns>
		protected internal abstract Subband split(WaveletFilter hfilter, WaveletFilter vfilter);