CSJ2K.j2k.entropy.encoder.EBCOTRateAllocator.initialize C# (CSharp) 메소드

initialize() 공개 메소드

Initializes the layers array. This must be called after the main header has been entirely written or simulated, so as to take its overhead into account. This method will get all the code-blocks and then initialize the target bitrates for each layer, according to the specifications.
public initialize ( ) : void
리턴 void
        public override void initialize()
        {
            int n, i, l;
            int ho; // The header overhead (in bytes)
            float np; // The number of pixels divided by the number of bits per byte
            double ls; // Step for log-scale
            double basebytes;
            int lastbytes, newbytes, nextbytes;
            int loopnlyrs;
            int minlsz; // The minimum allowable number of bytes in a layer
            int totenclength;
            int maxpkt;
            int numTiles = src.getNumTiles();
            int numComps = src.NumComps;
            int numLvls;
            int avgPktLen;
            #if DO_TIMING
            long stime = 0L;
            #endif
            // Start by getting all the code-blocks, we need this in order to have
            // an idea of the total encoded bitrate.
            getAllCodeBlocks();

            #if DO_TIMING
                stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
            #endif

            // Now get the total encoded length
            totenclength = RDSlopesRates[0]; // all the encoded data
            // Make a rough estimation of the packet head overhead, as 2 bytes per
            // packet in average (plus EPH / SOP) , and add that to the total
            // encoded length
            for (int t = 0; t < numTiles; t++)
            {
                avgPktLen = 2;
                // Add SOP length if set
                if (((System.String) encSpec.sops.getTileDef(t)).ToUpper().Equals("on".ToUpper()))
                {
                    avgPktLen += CSJ2K.j2k.codestream.Markers.SOP_LENGTH;
                }
                // Add EPH length if set
                if (((System.String) encSpec.ephs.getTileDef(t)).ToUpper().Equals("on".ToUpper()))
                {
                    avgPktLen += CSJ2K.j2k.codestream.Markers.EPH_LENGTH;
                }

                for (int c = 0; c < numComps; c++)
                {
                    numLvls = src.getAnSubbandTree(t, c).resLvl + 1;
                    if (!src.precinctPartitionUsed(c, t))
                    {
                        // Precinct partition is not used so there is only
                        // one packet per resolution level/layer
                        totenclength += num_Layers * avgPktLen * numLvls;
                    }
                    else
                    {
                        // Precinct partition is used so for each
                        // component/tile/resolution level, we get the maximum
                        // number of packets
                        for (int rl = 0; rl < numLvls; rl++)
                        {
                            maxpkt = numPrec[t][c][rl].x * numPrec[t][c][rl].y;
                            totenclength += num_Layers * avgPktLen * maxpkt;
                        }
                    }
                } // End loop on components
            } // End loop on tiles

            // If any layer specifies more than 'totenclength' as its target
            // length then 'totenclength' is used. This is to prevent that
            // estimated layers get excessively large target lengths due to an
            // excessively large target bitrate. At the end the last layer is set
            // to the target length corresponding to the overall target
            // bitrate. Thus, 'totenclength' can not limit the total amount of
            // encoded data, as intended.

            ho = headEnc.Length;
            np = src.ImgWidth * src.ImgHeight / 8f;

            // SOT marker must be taken into account
            for (int t = 0; t < numTiles; t++)
            {
                headEnc.reset();
                headEnc.encodeTilePartHeader(0, t);
                ho += headEnc.Length;
            }

            layers = new EBCOTLayer[num_Layers];
            for (n = num_Layers - 1; n >= 0; n--)
            {
                layers[n] = new EBCOTLayer();
            }

            minlsz = 0; // To keep compiler happy
            for (int t = 0; t < numTiles; t++)
            {
                for (int c = 0; c < numComps; c++)
                {
                    numLvls = src.getAnSubbandTree(t, c).resLvl + 1;

                    if (!src.precinctPartitionUsed(c, t))
                    {
                        // Precinct partition is not used
                        minlsz += MIN_AVG_PACKET_SZ * numLvls;
                    }
                    else
                    {
                        // Precinct partition is used
                        for (int rl = 0; rl < numLvls; rl++)
                        {
                            maxpkt = numPrec[t][c][rl].x * numPrec[t][c][rl].y;
                            minlsz += MIN_AVG_PACKET_SZ * maxpkt;
                        }
                    }
                } // End loop on components
            } // End loop on tiles

            // Initialize layers
            n = 0;
            i = 0;
            lastbytes = 0;

            while (n < num_Layers - 1)
            {
                // At an optimized layer
                basebytes = System.Math.Floor(lyrSpec.getTargetBitrate(i) * np);
                if (i < lyrSpec.NOptPoints - 1)
                {
                    //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'"
                    nextbytes = (int) (lyrSpec.getTargetBitrate(i + 1) * np);
                    // Limit target length to 'totenclength'
                    if (nextbytes > totenclength)
                        nextbytes = totenclength;
                }
                else
                {
                    nextbytes = 1;
                }
                loopnlyrs = lyrSpec.getExtraLayers(i) + 1;
                ls = System.Math.Exp(System.Math.Log((double) nextbytes / basebytes) / loopnlyrs);
                layers[n].optimize = true;
                for (l = 0; l < loopnlyrs; l++)
                {
                    //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'"
                    newbytes = (int) basebytes - lastbytes - ho;
                    if (newbytes < minlsz)
                    {
                        // Skip layer (too small)
                        basebytes *= ls;
                        num_Layers--;
                        continue;
                    }
                    //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'"
                    lastbytes = (int) basebytes - ho;
                    layers[n].maxBytes = lastbytes;
                    basebytes *= ls;
                    n++;
                }
                i++; // Goto next optimization point
            }

            // Ensure minimum size of last layer (this one determines overall
            // bitrate)
            n = num_Layers - 2;
            //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'"
            nextbytes = (int) (lyrSpec.TotBitrate * np) - ho;
            newbytes = nextbytes - ((n >= 0)?layers[n].maxBytes:0);
            while (newbytes < minlsz)
            {
                if (num_Layers == 1)
                {
                    if (newbytes <= 0)
                    {
                        throw new System.ArgumentException("Overall target bitrate too " + "low, given the current " + "bit stream header overhead");
                    }
                    break;
                }
                // Delete last layer
                num_Layers--;
                n--;
                newbytes = nextbytes - ((n >= 0)?layers[n].maxBytes:0);
            }
            // Set last layer to the overall target bitrate
            n++;
            layers[n].maxBytes = nextbytes;
            layers[n].optimize = true;

            // Re-initialize progression order changes if needed Default values
            Progression[] prog1; // prog2 removed
            prog1 = (Progression[]) encSpec.pocs.getDefault();
            int nValidProg = prog1.Length;
            for (int prg = 0; prg < prog1.Length; prg++)
            {
                if (prog1[prg].lye > num_Layers)
                {
                    prog1[prg].lye = num_Layers;
                }
            }
            if (nValidProg == 0)
            {
                throw new System.InvalidOperationException("Unable to initialize rate allocator: No " + "default progression type has been defined.");
            }

            // Tile specific values
            for (int t = 0; t < numTiles; t++)
            {
                if (encSpec.pocs.isTileSpecified(t))
                {
                    prog1 = (Progression[]) encSpec.pocs.getTileDef(t);
                    nValidProg = prog1.Length;
                    for (int prg = 0; prg < prog1.Length; prg++)
                    {
                        if (prog1[prg].lye > num_Layers)
                        {
                            prog1[prg].lye = num_Layers;
                        }
                    }
                    if (nValidProg == 0)
                    {
                        throw new System.InvalidOperationException("Unable to initialize rate allocator:" + " No default progression type has been " + "defined for tile " + t);
                    }
                }
            } // End loop on tiles

            #if DO_TIMING
            initTime += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
            #endif
        }