Пример #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 SynWTFilter object.
        ///
        /// </param>
        /// <param name="vfilter">The vertical wavelet filter used to decompose this
        /// subband. It has to be a SynWTFilter 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 = (SynWTFilter)hfilter;
            this.vFilter = (SynWTFilter)vfilter;

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

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

            // Initialize childs
            initChilds();

            // Return reference to LL subband
            return(subb_LL);
        }
Пример #2
0
        /// <summary> Returns the specified code-block in the current tile for the specified
        /// component (as a reference or copy).
        ///
        /// <p>The returned code-block may be progressive, which is indicated by
        /// the 'progressive' variable of the returned 'DataBlk' object. If a
        /// code-block is progressive it means that in a later request to this
        /// method for the same code-block it is possible to retrieve data which is
        /// a better approximation, since meanwhile more data to decode for the
        /// code-block could have been received. If the code-block is not
        /// progressive then later calls to this method for the same code-block
        /// will return the exact same data values.</p>
        ///
        /// <p>The data returned by this method can be the data in the internal
        /// buffer of this object, if any, and thus can not be modified by the
        /// caller. The 'offset' and 'scanw' of the returned data can be
        /// arbitrary. See the 'DataBlk' class.</p>
        ///
        /// <p>The 'ulx' and 'uly' members of the returned 'DataBlk' object contain
        /// the coordinates of the top-left corner of the block, with respect to
        /// the tile, not the subband.</p>
        ///
        /// </summary>
        /// <param name="c">The component for which to return the next code-block.
        ///
        /// </param>
        /// <param name="m">The vertical index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="n">The horizontal index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="sb">The subband in which the code-block to return is.
        ///
        /// </param>
        /// <param name="cblk">If non-null this object will be used to return the new
        /// code-block. If null a new one will be allocated and returned. If the
        /// "data" array of the object is non-null it will be reused, if possible,
        /// to return the data.
        ///
        /// </param>
        /// <returns> The requested code-block in the current tile for component 'c'.
        ///
        /// </returns>
        /// <seealso cref="DataBlk">
        ///
        /// </seealso>
        public virtual DataBlk getInternCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
        {
            int i, j, k, wrap; // mi removed
            int ulx, uly, w, h;

            int[] data; // local copy of quantized data
            int   tmp;

            //int limit;

            // Get data block from entropy decoder
            cblk = src.getInternCodeBlock(c, m, n, sb, cblk);

            // If there are no ROIs in the tile, Or if we already got all blocks
            bool noRoiInTile = false;

            if (mss == null || mss.getTileCompVal(TileIdx, c) == null)
            {
                noRoiInTile = true;
            }

            if (noRoiInTile || cblk == null)
            {
                return(cblk);
            }
            data = (int[])cblk.Data;
            ulx  = cblk.ulx;
            uly  = cblk.uly;
            w    = cblk.w;
            h    = cblk.h;

            // Scale coefficients according to magnitude. If the magnitude of a
            // coefficient is lower than 2 pow 31-magbits then it is a background
            // coeff and should be up-scaled
            int boost = ((System.Int32)mss.getTileCompVal(TileIdx, c));
            int mask  = ((1 << sb.magbits) - 1) << (31 - sb.magbits);
            int mask2 = (~mask) & 0x7FFFFFFF;

            wrap = cblk.scanw - w;
            i    = cblk.offset + cblk.scanw * (h - 1) + w - 1;
            for (j = h; j > 0; j--)
            {
                for (k = w; k > 0; k--, i--)
                {
                    tmp = data[i];
                    if ((tmp & mask) == 0)
                    {
                        // BG
                        data[i] = (tmp & unchecked ((int)0x80000000)) | (tmp << boost);
                    }
                    else
                    {
                        // ROI
                        if ((tmp & mask2) != 0)
                        {
                            // decoded more than magbits bit-planes, set
                            // quantization mid-interval approx. bit just after
                            // the magbits.
                            data[i] = (tmp & (~mask2)) | (1 << (30 - sb.magbits));
                        }
                    }
                }
                i -= wrap;
            }
            return(cblk);
        }
Пример #3
0
 /// <summary> Returns the specified code-block in the current tile for the specified
 /// component, as a copy (see below).
 ///
 /// <p>The returned code-block may be progressive, which is indicated by
 /// the 'progressive' variable of the returned 'DataBlk' object. If a
 /// code-block is progressive it means that in a later request to this
 /// method for the same code-block it is possible to retrieve data which is
 /// a better approximation, since meanwhile more data to decode for the
 /// code-block could have been received. If the code-block is not
 /// progressive then later calls to this method for the same code-block
 /// will return the exact same data values.</p>
 ///
 /// <p>The data returned by this method is always a copy of the internal
 /// data of this object, if any, and it can be modified "in place" without
 /// any problems after being returned. The 'offset' of the returned data is
 /// 0, and the 'scanw' is the same as the code-block width. See the
 /// 'DataBlk' class.</p>
 ///
 /// <p>The 'ulx' and 'uly' members of the returned 'DataBlk' object contain
 /// the coordinates of the top-left corner of the block, with respect to
 /// the tile, not the subband.</p>
 ///
 /// </summary>
 /// <param name="c">The component for which to return the next code-block.
 ///
 /// </param>
 /// <param name="m">The vertical index of the code-block to return, in the
 /// specified subband.
 ///
 /// </param>
 /// <param name="n">The horizontal index of the code-block to return, in the
 /// specified subband.
 ///
 /// </param>
 /// <param name="sb">The subband in which the code-block to return is.
 ///
 /// </param>
 /// <param name="cblk">If non-null this object will be used to return the new
 /// code-block. If null a new one will be allocated and returned. If the
 /// "data" array of the object is non-null it will be reused, if possible,
 /// to return the data.
 ///
 /// </param>
 /// <returns> The next code-block in the current tile for component 'c', or
 /// null if all code-blocks for the current tile have been returned.
 ///
 /// </returns>
 /// <seealso cref="DataBlk">
 ///
 /// </seealso>
 public virtual DataBlk getCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
 {
     return(getInternCodeBlock(c, m, n, sb, cblk));
 }
Пример #4
0
        /// <summary> Returns the specified code-block in the current tile for the specified
        /// component (as a reference or copy).
        ///
        /// <p>The returned code-block may be progressive, which is indicated by
        /// the 'progressive' variable of the returned 'DataBlk'
        /// object. If a code-block is progressive it means that in a later request
        /// to this method for the same code-block it is possible to retrieve data
        /// which is a better approximation, since meanwhile more data to decode
        /// for the code-block could have been received. If the code-block is not
        /// progressive then later calls to this method for the same code-block
        /// will return the exact same data values.</p>
        ///
        /// <p>The data returned by this method can be the data in the internal
        /// buffer of this object, if any, and thus can not be modified by the
        /// caller. The 'offset' and 'scanw' of the returned data can be
        /// arbitrary. See the 'DataBlk' class.</p>
        ///
        /// </summary>
        /// <param name="c">The component for which to return the next code-block.
        ///
        /// </param>
        /// <param name="m">The vertical index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="n">The horizontal index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="sb">The subband in which the code-block to return is.
        ///
        /// </param>
        /// <param name="cblk">If non-null this object will be used to return the new
        /// code-block. If null a new one will be allocated and returned. If the
        /// "data" array of the object is non-null it will be reused, if possible,
        /// to return the data.
        ///
        /// </param>
        /// <returns> The next code-block in the current tile for component 'n', or
        /// null if all code-blocks for the current tile have been returned.
        ///
        /// </returns>
        /// <seealso cref="DataBlk">
        ///
        /// </seealso>
        public override DataBlk getInternCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
        {
            // This method is declared final since getNextCodeBlock() relies on
            // the actual implementation of this method.
            int   j, jmin, k;
            int   temp;
            float step;
            int   shiftBits;
            int   magBits;

            int[]   outiarr, inarr;
            float[] outfarr;
            int     w, h;
            bool    reversible = qts.isReversible(tIdx, c);
            bool    derived    = qts.isDerived(tIdx, c);
            StdDequantizerParams params_Renamed = (StdDequantizerParams)qsss.getTileCompVal(tIdx, c);
            int G = ((System.Int32)gbs.getTileCompVal(tIdx, c));

            outdtype = cblk.DataType;

            if (reversible && outdtype != DataBlk.TYPE_INT)
            {
                throw new System.ArgumentException("Reversible quantizations " + "must use int data");
            }

            // To get compiler happy
            outiarr = null;
            outfarr = null;
            inarr   = null;

            // Get source data and initialize output DataBlk object.
            switch (outdtype)
            {
            case DataBlk.TYPE_INT:
                // With int data we can use the same DataBlk object to get the
                // data from the source and return the dequantized data, and we
                // can also work "in place" (i.e. same buffer).
                cblk = src.getCodeBlock(c, m, n, sb, cblk);
                // Input and output arrays are the same
                outiarr = (int[])cblk.Data;
                break;

            case DataBlk.TYPE_FLOAT:
                // With float data we must use a different DataBlk objects to get
                // the data from the source and to return the dequantized data.
                inblk = (DataBlkInt)src.getInternCodeBlock(c, m, n, sb, inblk);
                inarr = inblk.DataInt;
                if (cblk == null)
                {
                    cblk = new DataBlkFloat();
                }
                // Copy the attributes of the CodeBlock object
                cblk.ulx         = inblk.ulx;
                cblk.uly         = inblk.uly;
                cblk.w           = inblk.w;
                cblk.h           = inblk.h;
                cblk.offset      = 0;
                cblk.scanw       = cblk.w;
                cblk.progressive = inblk.progressive;
                // Get output data array and check its size
                outfarr = (float[])cblk.Data;
                if (outfarr == null || outfarr.Length < cblk.w * cblk.h)
                {
                    outfarr   = new float[cblk.w * cblk.h];
                    cblk.Data = outfarr;
                }
                break;
            }

            magBits = sb.magbits;

            // Calculate quantization step and number of magnitude bits
            // depending on reversibility and derivedness and perform
            // inverse quantization
            if (reversible)
            {
                shiftBits = 31 - magBits;
                // For int data Inverse quantization happens "in-place". The input
                // array has an offset of 0 and scan width equal to the code-block
                // width.
                for (j = outiarr.Length - 1; j >= 0; j--)
                {
                    temp       = outiarr[j]; // input array is same as output one
                    outiarr[j] = (temp >= 0) ? (temp >> shiftBits) : -((temp & 0x7FFFFFFF) >> shiftBits);
                }
            }
            else
            {
                // Not reversible
                if (derived)
                {
                    // Max resolution level
                    int mrl = src.getSynSubbandTree(TileIdx, c).resLvl;
                    step = params_Renamed.nStep[0][0] * (1L << (rb[c] + sb.anGainExp + mrl - sb.level));
                }
                else
                {
                    step = params_Renamed.nStep[sb.resLvl][sb.sbandIdx] * (1L << (rb[c] + sb.anGainExp));
                }
                shiftBits = 31 - magBits;

                // Adjust step to the number of shiftBits
                step /= (1 << shiftBits);

                switch (outdtype)
                {
                case DataBlk.TYPE_INT:
                    // For int data Inverse quantization happens "in-place". The
                    // input array has an offset of 0 and scan width equal to the
                    // code-block width.
                    for (j = outiarr.Length - 1; j >= 0; j--)
                    {
                        temp = outiarr[j];     // input array is same as output one
                                               //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'"
                        outiarr[j] = (int)(((float)((temp >= 0) ? temp : -(temp & 0x7FFFFFFF))) * step);
                    }
                    break;

                case DataBlk.TYPE_FLOAT:
                    // For float data the inverse quantization can not happen
                    // "in-place".
                    w = cblk.w;
                    h = cblk.h;
                    for (j = w * h - 1, k = inblk.offset + (h - 1) * inblk.scanw + w - 1, jmin = w * (h - 1); j >= 0; jmin -= w)
                    {
                        for (; j >= jmin; k--, j--)
                        {
                            temp = inarr[k];
                            //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'"
                            outfarr[j] = ((float)((temp >= 0) ? temp : -(temp & 0x7FFFFFFF))) * step;
                        }
                        // Jump to beggining of previous line in input
                        k -= (inblk.scanw - w);
                    }
                    break;
                }
            }
            // Return the output code-block
            return(cblk);
        }