CSJ2K.j2k.codestream.writer.HeaderEncoder.writeMainQCD C# (CSharp) Method

writeMainQCD() protected method

Writes QCD marker segment in main header. QCD is a functional marker segment countaining the quantization default used for compressing all the components in an image. The values can be overriden for an individual component by a QCC marker in either the main or the tile header.
protected writeMainQCD ( ) : void
return void
        protected internal virtual void writeMainQCD()
        {
            int mrl;
            int qstyle;

            float step;

            System.String qType = (System.String) encSpec.qts.getDefault();
            //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'"
            float baseStep = (float) ((System.Single) encSpec.qsss.getDefault());
            int gb = ((System.Int32) encSpec.gbs.getDefault());

            bool isDerived = qType.Equals("derived");
            bool isReversible = qType.Equals("reversible");

            mrl = ((System.Int32) encSpec.dls.getDefault());

            int nt = dwt.getNumTiles();
            int nc = dwt.NumComps;
            int tmpI;
            int[] tcIdx = new int[2];
            System.String tmpStr;
            bool notFound = true;
            for (int t = 0; t < nt && notFound; t++)
            {
                for (int c = 0; c < nc && notFound; c++)
                {
                    tmpI = ((System.Int32) encSpec.dls.getTileCompVal(t, c));
                    tmpStr = ((System.String) encSpec.qts.getTileCompVal(t, c));
                    if (tmpI == mrl && tmpStr.Equals(qType))
                    {
                        tcIdx[0] = t; tcIdx[1] = c;
                        notFound = false;
                    }
                }
            }
            if (notFound)
            {
                throw new System.InvalidOperationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCD marker segment. " + "You have found a JJ2000 bug.");
            }
            SubbandAn sb, csb, sbRoot = dwt.getAnSubbandTree(tcIdx[0], tcIdx[1]);
            defimgn = dwt.getNomRangeBits(tcIdx[1]);

            int nqcd; // Number of quantization step-size to transmit

            // Get the quantization style
            qstyle = (isReversible)?CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:((isDerived)?CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED);

            // QCD marker
            hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.QCD);

            // Compute the number of steps to send
            switch (qstyle)
            {

                case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:
                    nqcd = 1; // Just the LL value
                    break;

                case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:
                case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED:
                    // One value per subband
                    nqcd = 0;

                    sb = sbRoot;

                    // Get the subband at first resolution level
                    sb = (SubbandAn) sb.getSubbandByIdx(0, 0);

                    // Count total number of subbands
                    for (int j = 0; j <= mrl; j++)
                    {
                        csb = sb;
                        while (csb != null)
                        {
                            nqcd++;
                            csb = (SubbandAn) csb.nextSubband();
                        }
                        // Go up one resolution level
                        sb = (SubbandAn) sb.NextResLevel;
                    }
                    break;

                default:
                    throw new System.InvalidOperationException("Internal JJ2000 error");

            }

            // Lqcd (marker segment length (in bytes))
            // Lqcd(2 bytes)+Sqcd(1)+ SPqcd (2*Nqcd)
            int markSegLen = 3 + ((isReversible)?nqcd:2 * nqcd);

            // Rounded to the nearest even value greater or equals
            hbuf.Write((System.Int16) markSegLen);

            // Sqcd
            hbuf.Write((System.Byte) (qstyle + (gb << CSJ2K.j2k.codestream.Markers.SQCX_GB_SHIFT)));

            // SPqcd
            switch (qstyle)
            {

                case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:
                    sb = sbRoot;
                    sb = (SubbandAn) sb.getSubbandByIdx(0, 0);

                    // Output one exponent per subband
                    for (int j = 0; j <= mrl; j++)
                    {
                        csb = sb;
                        while (csb != null)
                        {
                            int tmp = (defimgn + csb.anGainExp);
                            hbuf.Write((System.Byte) (tmp << CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT));

                            csb = (SubbandAn) csb.nextSubband();
                            // Go up one resolution level
                        }
                        sb = (SubbandAn) sb.NextResLevel;
                    }
                    break;

                case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:
                    sb = sbRoot;
                    sb = (SubbandAn) sb.getSubbandByIdx(0, 0);

                    // Calculate subband step (normalized to unit
                    // dynamic range)
                    step = baseStep / (1 << sb.level);

                    // Write exponent-mantissa, 16 bits
                    hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step));
                    break;

                case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED:
                    sb = sbRoot;
                    sb = (SubbandAn) sb.getSubbandByIdx(0, 0);

                    // Output one step per subband
                    for (int j = 0; j <= mrl; j++)
                    {
                        csb = sb;
                        while (csb != null)
                        {
                            // Calculate subband step (normalized to unit
                            // dynamic range)
                            step = baseStep / (csb.l2Norm * (1 << csb.anGainExp));

                            // Write exponent-mantissa, 16 bits
                            hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step));

                            csb = (SubbandAn) csb.nextSubband();
                        }
                        // Go up one resolution level
                        sb = (SubbandAn) sb.NextResLevel;
                    }
                    break;

                default:
                    throw new System.InvalidOperationException("Internal JJ2000 error");

            }
        }