CSJ2K.j2k.codestream.reader.HeaderDecoder.readQCC C# (CSharp) Method

readQCC() private method

Reads a QCC marker segment and realigns the codestream at the point where the next marker should be found. QCC is a functional marker segment that describes the quantization of one component.
If an I/O error occurs while reading from the /// encoded header stream. /// ///
private readQCC ( System ehs, bool mainh, int tileIdx, int tpIdx ) : void
ehs System The encoded stream. /// ///
mainh bool Flag indicating whether or not this marker segment is read /// from the main header. /// ///
tileIdx int The index of the current tile /// ///
tpIdx int Tile-part index /// ///
return void
        private void readQCC(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int tpIdx)
        {
            int cComp; // current component
            int tmp;
            StdDequantizerParams qParms;
            int[][] expC;
            float[][] nStepC = null;
            HeaderInfo.QCC ms = hi.NewQCC;

            // Lqcc (length of QCC field)
            ms.lqcc = ehs.ReadUInt16();

            // Cqcc
            if (nComp < 257)
            {
                cComp = ms.cqcc = ehs.ReadByte();
            }
            else
            {
                cComp = ms.cqcc = ehs.ReadUInt16();
            }
            if (cComp >= nComp)
            {
                throw new CorruptedCodestreamException("Invalid component " + "index in QCC marker");
            }

            // Sqcc (quantization style)
            ms.sqcc = ehs.ReadByte();
            int guardBits = ms.NumGuardBits;
            int qType = ms.QuantType;

            if (mainh)
            {
                hi.qccValue["main_c" + cComp] = ms;
                // If main header is being read, set default for component in all
                // tiles
                switch (qType)
                {

                    case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:
                        decSpec.qts.setCompDef(cComp, "reversible");
                        break;

                    case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:
                        decSpec.qts.setCompDef(cComp, "derived");
                        break;

                    case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED:
                        decSpec.qts.setCompDef(cComp, "expounded");
                        break;

                    default:
                        throw new CorruptedCodestreamException("Unknown or " + "unsupported " + "quantization style " + "in Sqcd field, QCD " + "marker, main header");

                }
            }
            else
            {
                hi.qccValue["t" + tileIdx + "_c" + cComp] = ms;
                // If tile header is being read, set value for component in
                // this tiles
                switch (qType)
                {

                    case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:
                        decSpec.qts.setTileCompVal(tileIdx, cComp, "reversible");
                        break;

                    case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:
                        decSpec.qts.setTileCompVal(tileIdx, cComp, "derived");
                        break;

                    case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED:
                        decSpec.qts.setTileCompVal(tileIdx, cComp, "expounded");
                        break;

                    default:
                        throw new CorruptedCodestreamException("Unknown or " + "unsupported " + "quantization style " + "in Sqcd field, QCD " + "marker, main header");

                }
            }

            // Decode all dequantizer params
            qParms = new StdDequantizerParams();

            if (qType == CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION)
            {
                int maxrl = (mainh?((System.Int32) decSpec.dls.getCompDef(cComp)):((System.Int32) decSpec.dls.getTileCompVal(tileIdx, cComp)));
                int j, rl; // i removed
                int minb, maxb, hpd;

                expC = qParms.exp = new int[maxrl + 1][];
                int[][] tmpArray = new int[maxrl + 1][];
                for (int i2 = 0; i2 < maxrl + 1; i2++)
                {
                    tmpArray[i2] = new int[4];
                }
                ms.spqcc = tmpArray;

                for (rl = 0; rl <= maxrl; rl++)
                {
                    // Loop on resolution levels
                    // Find the number of subbands in the resolution level
                    if (rl == 0)
                    {
                        // Only the LL subband
                        minb = 0;
                        maxb = 1;
                    }
                    else
                    {
                        // Dyadic decomposition
                        hpd = 1;

                        // Adapt hpd to resolution level
                        if (hpd > maxrl - rl)
                        {
                            hpd -= (maxrl - rl);
                        }
                        else
                        {
                            hpd = 1;
                        }
                        // Determine max and min subband index
                        minb = 1 << ((hpd - 1) << 1); // minb = 4^(hpd-1)
                        maxb = 1 << (hpd << 1); // maxb = 4^hpd
                    }
                    // Allocate array for subbands in resolution level
                    expC[rl] = new int[maxb];

                    for (j = minb; j < maxb; j++)
                    {
                        tmp = ms.spqcc[rl][j] = ehs.ReadByte();
                        expC[rl][j] = (tmp >> CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT) & CSJ2K.j2k.codestream.Markers.SQCX_EXP_MASK;
                    }
                } // end for rl
            }
            else
            {
                int maxrl = (qType == CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED)?0:(mainh?((System.Int32) decSpec.dls.getCompDef(cComp)):((System.Int32) decSpec.dls.getTileCompVal(tileIdx, cComp)));
                int j, rl; // i removed
                int minb, maxb, hpd;

                nStepC = qParms.nStep = new float[maxrl + 1][];
                expC = qParms.exp = new int[maxrl + 1][];
                int[][] tmpArray2 = new int[maxrl + 1][];
                for (int i3 = 0; i3 < maxrl + 1; i3++)
                {
                    tmpArray2[i3] = new int[4];
                }
                ms.spqcc = tmpArray2;

                for (rl = 0; rl <= maxrl; rl++)
                {
                    // Loop on resolution levels
                    // Find the number of subbands in the resolution level
                    if (rl == 0)
                    {
                        // Only the LL subband
                        minb = 0;
                        maxb = 1;
                    }
                    else
                    {
                        // Dyadic decomposition
                        hpd = 1;

                        // Adapt hpd to resolution level
                        if (hpd > maxrl - rl)
                        {
                            hpd -= (maxrl - rl);
                        }
                        else
                        {
                            hpd = 1;
                        }
                        // Determine max and min subband index
                        minb = 1 << ((hpd - 1) << 1); // minb = 4^(hpd-1)
                        maxb = 1 << (hpd << 1); // maxb = 4^hpd
                    }
                    // Allocate array for subbands in resolution level
                    expC[rl] = new int[maxb];
                    nStepC[rl] = new float[maxb];

                    for (j = minb; j < maxb; j++)
                    {
                        tmp = ms.spqcc[rl][j] = ehs.ReadUInt16();
                        expC[rl][j] = (tmp >> 11) & 0x1f;
                        // NOTE: the formula below does not support more than 5
                        // bits for the exponent, otherwise (-1<<exp) might
                        // overflow (the - is used to be able to represent 2**31)
                        //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'"
                        nStepC[rl][j] = (- 1f - ((float) (tmp & 0x07ff)) / (1 << 11)) / (- 1 << expC[rl][j]);
                    }
                } // end for rl
            } // end if (qType != SQCX_NO_QUANTIZATION)

            // Fill qsss, gbs
            if (mainh)
            {
                decSpec.qsss.setCompDef(cComp, qParms);
                decSpec.gbs.setCompDef(cComp, (System.Object) guardBits);
            }
            else
            {
                decSpec.qsss.setTileCompVal(tileIdx, cComp, qParms);
                decSpec.gbs.setTileCompVal(tileIdx, cComp, (System.Object) guardBits);
            }

            // Check marker length
            checkMarkerLength(ehs, "QCC marker");
        }