CSJ2K.j2k.codestream.reader.PktDecoder.readPktHead C# (CSharp) 메소드

readPktHead() 공개 메소드

Read specified packet head and found length of each code-block's piece of codewords as well as number of skipped most significant bit-planes.
public readPktHead ( int l, int r, int c, int p, CSJ2K.j2k.codestream.reader.CBlkInfo cbI, int nb ) : bool
l int layer index /// ///
r int Resolution level index /// ///
c int Component index /// ///
p int Precinct index /// ///
cbI CSJ2K.j2k.codestream.reader.CBlkInfo CBlkInfo array of relevant component and resolution /// level. /// ///
nb int The number of bytes to read in each tile before reaching /// output rate (used by truncation mode) /// ///
리턴 bool
        public virtual bool readPktHead(int l, int r, int c, int p, CBlkInfo[][][] cbI, int[] nb)
        {
            CBlkInfo ccb;
            int nSeg; // number of segment to read
            int cbLen; // Length of cblk's code-words
            int ltp; // last truncation point index
            int passtype; // coding pass type
            TagTreeDecoder tdIncl, tdBD;
            int tmp, tmp2, totnewtp, lblockCur, tpidx;
            int sumtotnewtp = 0;
            Coord cbc;
            int startPktHead = ehs.Pos;
            if (startPktHead >= ehs.length())
            {
                // EOF reached at the beginning of this packet head
                return true;
            }
            int tIdx = src.TileIdx;
            PktHeaderBitReader bin;
            int mend, nend;
            int b;
            SubbandSyn sb;
            SubbandSyn root = src.getSynSubbandTree(tIdx, c);

            // If packed packet headers was used, use separate stream for reading
            // of packet headers
            if (pph)
            {
                bin = new PktHeaderBitReader(pphbais);
            }
            else
            {
                bin = this.bin;
            }

            int mins = (r == 0)?0:1;
            int maxs = (r == 0)?1:4;

            bool precFound = false;
            for (int s = mins; s < maxs; s++)
            {
                if (p < ppinfo[c][r].Length)
                {
                    precFound = true;
                }
            }
            if (!precFound)
            {
                return false;
            }

            PrecInfo prec = ppinfo[c][r][p];

            // Synchronize for bit reading
            bin.sync();

            // If packet is empty there is no info in it (i.e. no code-blocks)
            if (bin.readBit() == 0)
            {
                // No code-block is included
                cblks = new List<CBlkCoordInfo>[maxs + 1];
                for (int s = mins; s < maxs; s++)
                {
                    cblks[s] = new List<CBlkCoordInfo>(10);
                }
                pktIdx++;

                // If truncation mode, checks if output rate is reached
                // unless ncb quit condition is used in which case headers
                // are not counted
                if (isTruncMode && maxCB == - 1)
                {
                    tmp = ehs.Pos - startPktHead;
                    if (tmp > nb[tIdx])
                    {
                        nb[tIdx] = 0;
                        return true;
                    }
                    else
                    {
                        nb[tIdx] -= tmp;
                    }
                }

                // Read EPH marker if needed
                if (ephUsed)
                {
                    readEPHMarker(bin);
                }
                return false;
            }

            // Packet is not empty => decode info
            // Loop on each subband in this resolution level
            if (cblks == null || cblks.Length < maxs + 1)
            {
                cblks = new List<CBlkCoordInfo>[maxs + 1];
            }

            for (int s = mins; s < maxs; s++)
            {
                if (cblks[s] == null)
                {
                    cblks[s] = new List<CBlkCoordInfo>(10);
                }
                else
                {
                    cblks[s].Clear();
                }
                sb = (SubbandSyn) root.getSubbandByIdx(r, s);
                // No code-block in this precinct
                if (prec.nblk[s] == 0)
                {
                    // Go to next subband
                    continue;
                }

                tdIncl = ttIncl[c][r][p][s];
                tdBD = ttMaxBP[c][r][p][s];

                mend = (prec.cblk[s] == null)?0:prec.cblk[s].Length;
                for (int m = 0; m < mend; m++)
                {
                    // Vertical code-blocks
                    nend = (prec.cblk[s][m] == null)?0:prec.cblk[s][m].Length;
                    for (int n = 0; n < nend; n++)
                    {
                        // Horizontal code-blocks
                        cbc = prec.cblk[s][m][n].idx;
                        b = cbc.x + cbc.y * sb.numCb.x;

                        ccb = cbI[s][cbc.y][cbc.x];

                        try
                        {
                            // If code-block not included in previous layer(s)
                            if (ccb == null || ccb.ctp == 0)
                            {
                                if (ccb == null)
                                {
                                    ccb = cbI[s][cbc.y][cbc.x] = new CBlkInfo(prec.cblk[s][m][n].ulx, prec.cblk[s][m][n].uly, prec.cblk[s][m][n].w, prec.cblk[s][m][n].h, nl);
                                }
                                ccb.pktIdx[l] = pktIdx;

                                // Read inclusion using tag-tree
                                tmp = tdIncl.update(m, n, l + 1, bin);
                                if (tmp > l)
                                {
                                    // Not included
                                    continue;
                                }

                                // Read bitdepth using tag-tree
                                tmp = 1; // initialization
                                for (tmp2 = 1; tmp >= tmp2; tmp2++)
                                {
                                    tmp = tdBD.update(m, n, tmp2, bin);
                                }
                                ccb.msbSkipped = tmp2 - 2;

                                // New code-block => at least one truncation point
                                totnewtp = 1;
                                ccb.addNTP(l, 0);

                                // Check whether ncb quit condition is reached
                                ncb++;

                                if (maxCB != - 1 && !ncbQuit && ncb == maxCB)
                                {
                                    // ncb quit contidion reached
                                    ncbQuit = true;
                                    tQuit = tIdx;
                                    cQuit = c;
                                    sQuit = s;
                                    rQuit = r;
                                    xQuit = cbc.x;
                                    yQuit = cbc.y;
                                }
                            }
                            else
                            {
                                // If code-block already included in one of
                                // the previous layers.

                                ccb.pktIdx[l] = pktIdx;

                                // If not inclused
                                if (bin.readBit() != 1)
                                {
                                    continue;
                                }

                                // At least 1 more truncation point than
                                // prev. packet
                                totnewtp = 1;
                            }

                            // Read new truncation points
                            if (bin.readBit() == 1)
                            {
                                // if bit is 1
                                totnewtp++;

                                // if next bit is 0 do nothing
                                if (bin.readBit() == 1)
                                {
                                    //if is 1
                                    totnewtp++;

                                    tmp = bin.readBits(2);
                                    totnewtp += tmp;

                                    // If next 2 bits are not 11 do nothing
                                    if (tmp == 0x3)
                                    {
                                        //if 11
                                        tmp = bin.readBits(5);
                                        totnewtp += tmp;

                                        // If next 5 bits are not 11111 do nothing
                                        if (tmp == 0x1F)
                                        {
                                            //if 11111
                                            totnewtp += bin.readBits(7);
                                        }
                                    }
                                }
                            }
                            ccb.addNTP(l, totnewtp);
                            sumtotnewtp += totnewtp;
                            cblks[s].Add(prec.cblk[s][m][n]);

                            // Code-block length

                            // -- Compute the number of bit to read to obtain
                            // code-block length.
                            // numBits = betaLamda + log2(totnewtp);

                            // The length is signalled for each segment in
                            // addition to the final one. The total length is the
                            // sum of all segment lengths.

                            // If regular termination in use, then there is one
                            // segment per truncation point present. Otherwise, if
                            // selective arithmetic bypass coding mode is present,
                            // then there is one termination per bypass/MQ and
                            // MQ/bypass transition. Otherwise the only
                            // termination is at the end of the code-block.
                            int options = ((System.Int32) decSpec.ecopts.getTileCompVal(tIdx, c));

                            if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
                            {
                                // Regular termination in use, one segment per new
                                // pass (i.e. truncation point)
                                nSeg = totnewtp;
                            }
                            else if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0)
                            {
                                // Selective arithmetic coding bypass coding mode
                                // in use, but no regular termination 1 segment up
                                // to the end of the last pass of the 4th most
                                // significant bit-plane, and, in each following
                                // bit-plane, one segment upto the end of the 2nd
                                // pass and one upto the end of the 3rd pass.

                                if (ccb.ctp <= CSJ2K.j2k.entropy.StdEntropyCoderOptions.FIRST_BYPASS_PASS_IDX)
                                {
                                    nSeg = 1;
                                }
                                else
                                {
                                    nSeg = 1; // One at least for last pass
                                    // And one for each other terminated pass
                                    for (tpidx = ccb.ctp - totnewtp; tpidx < ccb.ctp - 1; tpidx++)
                                    {
                                        if (tpidx >= CSJ2K.j2k.entropy.StdEntropyCoderOptions.FIRST_BYPASS_PASS_IDX - 1)
                                        {
                                            passtype = (tpidx + CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_EMPTY_PASSES_IN_MS_BP) % CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES;
                                            if (passtype == 1 || passtype == 2)
                                            {
                                                // bypass coding just before MQ
                                                // pass or MQ pass just before
                                                // bypass coding => terminated
                                                nSeg++;
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // Nothing special in use, just one segment
                                nSeg = 1;
                            }

                            // Reads lblock increment (common to all segments)
                            while (bin.readBit() != 0)
                            {
                                lblock[c][r][s][cbc.y][cbc.x]++;
                            }

                            if (nSeg == 1)
                            {
                                // Only one segment in packet
                                cbLen = bin.readBits(lblock[c][r][s][cbc.y][cbc.x] + MathUtil.log2(totnewtp));
                            }
                            else
                            {
                                // We must read one length per segment
                                ccb.segLen[l] = new int[nSeg];
                                cbLen = 0;
                                int j;
                                if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
                                {
                                    // Regular termination: each pass is terminated
                                    for (tpidx = ccb.ctp - totnewtp, j = 0; tpidx < ccb.ctp; tpidx++, j++)
                                    {

                                        lblockCur = lblock[c][r][s][cbc.y][cbc.x];

                                        tmp = bin.readBits(lblockCur);
                                        ccb.segLen[l][j] = tmp;
                                        cbLen += tmp;
                                    }
                                }
                                else
                                {
                                    // Bypass coding: only some passes are
                                    // terminated
                                    ltp = ccb.ctp - totnewtp - 1;
                                    for (tpidx = ccb.ctp - totnewtp, j = 0; tpidx < ccb.ctp - 1; tpidx++)
                                    {
                                        if (tpidx >= CSJ2K.j2k.entropy.StdEntropyCoderOptions.FIRST_BYPASS_PASS_IDX - 1)
                                        {
                                            passtype = (tpidx + CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_EMPTY_PASSES_IN_MS_BP) % CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES;
                                            if (passtype == 0)
                                                continue;

                                            lblockCur = lblock[c][r][s][cbc.y][cbc.x];
                                            tmp = bin.readBits(lblockCur + MathUtil.log2(tpidx - ltp));
                                            ccb.segLen[l][j] = tmp;
                                            cbLen += tmp;
                                            ltp = tpidx;
                                            j++;
                                        }
                                    }
                                    // Last pass has always the length sent
                                    lblockCur = lblock[c][r][s][cbc.y][cbc.x];
                                    tmp = bin.readBits(lblockCur + MathUtil.log2(tpidx - ltp));
                                    cbLen += tmp;
                                    ccb.segLen[l][j] = tmp;
                                }
                            }
                            ccb.len[l] = cbLen;

                            // If truncation mode, checks if output rate is reached
                            // unless ncb and lbody quit contitions used.
                            if (isTruncMode && maxCB == - 1)
                            {
                                tmp = ehs.Pos - startPktHead;
                                if (tmp > nb[tIdx])
                                {
                                    nb[tIdx] = 0;
                                    // Remove found information in this code-block
                                    if (l == 0)
                                    {
                                        cbI[s][cbc.y][cbc.x] = null;
                                    }
                                    else
                                    {
                                        ccb.off[l] = ccb.len[l] = 0;
                                        ccb.ctp -= ccb.ntp[l];
                                        ccb.ntp[l] = 0;
                                        ccb.pktIdx[l] = - 1;
                                    }
                                    return true;
                                }
                            }
                        }
                        catch (System.IO.EndOfStreamException e)
                        {
                            // Remove found information in this code-block
                            if (l == 0)
                            {
                                cbI[s][cbc.y][cbc.x] = null;
                            }
                            else
                            {
                                ccb.off[l] = ccb.len[l] = 0;
                                ccb.ctp -= ccb.ntp[l];
                                ccb.ntp[l] = 0;
                                ccb.pktIdx[l] = - 1;
                            }
                            //                         throw new EOFException();
                            return true;
                        }
                    } // End loop on horizontal code-blocks
                } // End loop on vertical code-blocks
            } // End loop on subbands

            // Read EPH marker if needed
            if (ephUsed)
            {
                readEPHMarker(bin);
            }

            pktIdx++;

            // If truncation mode, checks if output rate is reached
            if (isTruncMode && maxCB == - 1)
            {
                tmp = ehs.Pos - startPktHead;
                if (tmp > nb[tIdx])
                {
                    nb[tIdx] = 0;
                    return true;
                }
                else
                {
                    nb[tIdx] -= tmp;
                }
            }
            return false;
        }