CSJ2K.j2k.codestream.reader.FileBitstreamReaderAgent.readTilePkts C# (CSharp) Méthode

readTilePkts() private méthode

Finish initialization of members for specified tile, reads packets head of each tile and keeps location of each code-block's codewords. The last 2 tasks are done by calling specific methods of PktDecoder.

Then, if a parsing output rate is defined, it keeps information of first layers only. This operation simulates a creation of a layer-resolution-component progressive bit-stream which will be next truncated and decoded.

private readTilePkts ( int t ) : void
t int Tile index /// ///
Résultat void
        private void readTilePkts(int t)
        {
            pktHL = new List<int>(10);

            // Number of layers
            int nl = ((System.Int32) decSpec.nls.getTileDef(t));

            // If packed packet headers was used, get the packet headers for this
            // tile
            if (((System.Boolean) decSpec.pphs.getTileDef(t)))
            {
                // Gets packed headers as separate input stream
                System.IO.MemoryStream pphbais = hd.getPackedPktHead(t);

                // Restarts PktDecoder instance
                cbI = pktDec.restart(this.nc, mdl, nl, cbI, true, pphbais);
            }
            else
            {
                // Restarts PktDecoder instance
                cbI = pktDec.restart(this.nc, mdl, nl, cbI, false, null);
            }

            // Reads packets of the tile according to the progression order
            int[][] pocSpec = ((int[][]) decSpec.pcs.getTileDef(t));
            int nChg = (pocSpec == null)?1:pocSpec.Length;

            // Create an array containing information about changes (progression
            // order type, layers index start, layer index end, resolution level
            // start, resolution level end, component index start, component index
            // end). There is one row per progresion order
            int[][] change = new int[nChg][];
            for (int i = 0; i < nChg; i++)
            {
                change[i] = new int[6];
            }
            int idx = 0; // Index of the current progression order

            change[0][1] = 0; // layer start

            if (pocSpec == null)
            {
                change[idx][0] = ((System.Int32) decSpec.pos.getTileDef(t));
                // Progression type found in COx marker segments
                change[idx][1] = nl; // Layer index end
                change[idx][2] = 0; // resolution level start
                change[idx][3] = decSpec.dls.getMaxInTile(t) + 1; // res. level end
                change[idx][4] = 0; // Component index start
                change[idx][5] = this.nc; // Component index end
            }
            else
            {
                for (idx = 0; idx < nChg; idx++)
                {
                    change[idx][0] = pocSpec[idx][5];
                    change[idx][1] = pocSpec[idx][2]; // layer end
                    change[idx][2] = pocSpec[idx][0]; // res. lev. start
                    change[idx][3] = pocSpec[idx][3]; // res. lev. end
                    change[idx][4] = pocSpec[idx][1]; // Comp. index start
                    change[idx][5] = pocSpec[idx][4]; // Comp. index end
                }
            }

            // Seeks to the first packet of the first tile-part
            try
            {
                // If in truncation mode, the first tile-part may be beyond the
                // target decoding rate. In this case, the offset of the first
                // packet is not defined.
                if (isTruncMode && firstPackOff == null || firstPackOff[t] == null)
                {
                    return ;
                }
                in_Renamed.seek(firstPackOff[t][0]);
            }
            catch (System.IO.EndOfStreamException e)
            {
                FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Codestream truncated in tile " + t);
                return ;
            }

            curTilePart = 0;

            // Start and end indexes for layers, resolution levels and components.
            int lye, ress, rese, comps, compe;
            bool status = false;
            int nb = nBytes[t];
            int[][] lys = new int[this.nc][];
            for (int c = 0; c < this.nc; c++)
            {
                lys[c] = new int[((System.Int32) decSpec.dls.getTileCompVal(t, c)) + 1];
            }

            try
            {
                for (int chg = 0; chg < nChg; chg++)
                {

                    lye = change[chg][1];
                    ress = change[chg][2];
                    rese = change[chg][3];
                    comps = change[chg][4];
                    compe = change[chg][5];

                    switch (change[chg][0])
                    {

                        case CSJ2K.j2k.codestream.ProgressionType.LY_RES_COMP_POS_PROG:
                            status = readLyResCompPos(lys, lye, ress, rese, comps, compe);
                            break;

                        case CSJ2K.j2k.codestream.ProgressionType.RES_LY_COMP_POS_PROG:
                            status = readResLyCompPos(lys, lye, ress, rese, comps, compe);
                            break;

                        case CSJ2K.j2k.codestream.ProgressionType.RES_POS_COMP_LY_PROG:
                            status = readResPosCompLy(lys, lye, ress, rese, comps, compe);
                            break;

                        case CSJ2K.j2k.codestream.ProgressionType.POS_COMP_RES_LY_PROG:
                            status = readPosCompResLy(lys, lye, ress, rese, comps, compe);
                            break;

                        case CSJ2K.j2k.codestream.ProgressionType.COMP_POS_RES_LY_PROG:
                            status = readCompPosResLy(lys, lye, ress, rese, comps, compe);
                            break;

                        default:
                            throw new System.ArgumentException("Not recognized " + "progression type");

                    }

                    // Update next first layer index
                    for (int c = comps; c < compe; c++)
                    {
                        if (c >= lys.Length)
                            continue;
                        for (int r = ress; r < rese; r++)
                        {
                            if (r >= lys[c].Length)
                                continue;
                            lys[c][r] = lye;
                        }
                    }

                    if (status || usePOCQuit)
                    {
                        break;
                    }
                }
            }
            catch (System.IO.EndOfStreamException e)
            {
                // Should never happen. Truncated codestream are normally found by
                // the class constructor
                throw e;
            }

            // In truncation mode, update the number of read bytes
            if (isTruncMode)
            {
                anbytes += nb - nBytes[t];

                // If truncation rate is reached
                if (status)
                {
                    nBytes[t] = 0;
                }
            }
            else if (nBytes[t] < (totTileLen[t] - totTileHeadLen[t]))
            {
                // In parsing mode, if there is not enough rate to entirely read the
                // tile. Then, parses the bit stream so as to create a virtual
                // layer-resolution-component progressive bit stream that will be
                // truncated and decoded afterwards.
                CBlkInfo cb;

                // Systematicaly reject all remaining code-blocks if one
                // code-block, at least, is refused.
                bool reject;
                // Stop reading any data from the bit stream
                bool stopCount = false;
                // Length of each packet's head (in an array)
                int[] pktHeadLen = new int[pktHL.Count];
                for (int i = pktHL.Count - 1; i >= 0; i--)
                {
                    pktHeadLen[i] = ((System.Int32) pktHL[i]);
                }

                // Parse each code-block, layer per layer until nBytes[t] is
                // reached
                reject = false;
                for (int l = 0; l < nl; l++)
                {
                    // layers
                    if (cbI == null)
                        continue;
                    int nc = cbI.Length;

                    int mres = 0;
                    for (int c = 0; c < nc; c++)
                    {
                        if (cbI[c] != null && cbI[c].Length > mres)
                            mres = cbI[c].Length;
                    }
                    for (int r = 0; r < mres; r++)
                    {
                        // resolutions

                        int msub = 0;
                        for (int c = 0; c < nc; c++)
                        {
                            if (cbI[c] != null && cbI[c][r] != null && cbI[c][r].Length > msub)
                                msub = cbI[c][r].Length;
                        }
                        for (int s = 0; s < msub; s++)
                        {
                            // subbands
                            // Only LL subband resolution level 0
                            if (r == 0 && s != 0)
                            {
                                continue;
                            }
                            else if (r != 0 && s == 0)
                            {
                                // No LL subband in resolution level > 0
                                continue;
                            }

                            int mnby = 0;
                            for (int c = 0; c < nc; c++)
                            {
                                if (cbI[c] != null && cbI[c][r] != null && cbI[c][r][s] != null && cbI[c][r][s].Length > mnby)
                                    mnby = cbI[c][r][s].Length;
                            }
                            for (int m = 0; m < mnby; m++)
                            {

                                int mnbx = 0;
                                for (int c = 0; c < nc; c++)
                                {
                                    if (cbI[c] != null && cbI[c][r] != null && cbI[c][r][s] != null && cbI[c][r][s][m] != null && cbI[c][r][s][m].Length > mnbx)
                                        mnbx = cbI[c][r][s][m].Length;
                                }
                                for (int n = 0; n < mnbx; n++)
                                {

                                    for (int c = 0; c < nc; c++)
                                    {

                                        if (cbI[c] == null || cbI[c][r] == null || cbI[c][r][s] == null || cbI[c][r][s][m] == null || cbI[c][r][s][m][n] == null)
                                        {
                                            continue;
                                        }
                                        cb = cbI[c][r][s][m][n];

                                        // If no code-block has been refused until
                                        // now
                                        if (!reject)
                                        {
                                            // Rate is to low to allow reading of
                                            // packet's head
                                            if (nBytes[t] < pktHeadLen[cb.pktIdx[l]])
                                            {
                                                // Stop parsing
                                                stopCount = true;
                                                // Reject all next
                                                // code-blocks
                                                reject = true;
                                            }
                                            else
                                            {
                                                // Rate is enough to read packet's
                                                // head
                                                if (!stopCount)
                                                {
                                                    //If parsing was not stopped
                                                    //Takes into account packet's
                                                    //head length
                                                    nBytes[t] -= pktHeadLen[cb.pktIdx[l]];
                                                    anbytes += pktHeadLen[cb.pktIdx[l]];
                                                    // Set packet's head length to
                                                    // 0, so that it won't be
                                                    // taken into account next
                                                    // time
                                                    pktHeadLen[cb.pktIdx[l]] = 0;
                                                }
                                            }
                                        }
                                        // Code-block has no data in this layer
                                        if (cb.len[l] == 0)
                                        {
                                            continue;
                                        }

                                        // Accepts code-block if length is enough,
                                        // if this code-block was not refused in a
                                        // previous layer and if no code-block was
                                        // refused in current component
                                        if (cb.len[l] < nBytes[t] && !reject)
                                        {
                                            nBytes[t] -= cb.len[l];
                                            anbytes += cb.len[l];
                                        }
                                        else
                                        {
                                            // Refuses code-block
                                            // Forgets code-block's data
                                            cb.len[l] = cb.off[l] = cb.ntp[l] = 0;
                                            // Refuses all other code-block in
                                            // current and next component
                                            reject = true;
                                        }
                                    } // End loop on components
                                } // End loop on horiz. code-blocks
                            } // End loop on vert. code-blocks
                        } // End loop on subbands
                    } // End loop on resolutions
                } // End loop on layers
            }
            else
            {
                // No parsing for this tile, adds tile's body to the total
                // number of read bytes.
                anbytes += totTileLen[t] - totTileHeadLen[t];
                if (t < getNumTiles() - 1)
                {
                    nBytes[t + 1] += nBytes[t] - (totTileLen[t] - totTileHeadLen[t]);
                }
            }
        }