예제 #1
0
 /// <summary> Returns true if given tile-component uses derived quantization step
 /// sizes.
 ///
 /// </summary>
 /// <param name="t">Tile index
 ///
 /// </param>
 /// <param name="c">Component index
 ///
 /// </param>
 /// <returns> True if derived
 ///
 /// </returns>
 public override bool isDerived(int t, int c)
 {
     return(qts.isDerived(t, c));
 }
예제 #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>
        ///
        /// </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);
        }