ebcotrateallocator.java

来自「jpeg2000编解码」· Java 代码 · 共 1,684 行 · 第 1/5 页

JAVA
1,684
字号
                    // Tile's coordinates in the reduced resolution image                    // domain                    trx0 = (int)Math.ceil(tcx0/(double)(1<<(mrl-1-r)));                    try0 = (int)Math.ceil(tcy0/(double)(1<<(mrl-1-r)));                    trx1 = (int)Math.ceil(tcx1/(double)(1<<(mrl-1-r)));                    try1 = (int)Math.ceil(tcy1/(double)(1<<(mrl-1-r)));                    // Calculate the maximum number of precincts for each                    // resolution level taking into account tile specific                    // options.                    double twoppx = (double)encSpec.pss.getPPX(t,c,r);                    double twoppy = (double)encSpec.pss.getPPY(t,c,r);                    numPrec[t][c][r] = new Coord();                    if (trx1>trx0) {                        numPrec[t][c][r].x = (int)Math.ceil((trx1-cb0x)/twoppx)                            - (int)Math.floor((trx0-cb0x)/twoppx);                    } else {                        numPrec[t][c][r].x = 0;                    }                    if (try1>try0) {                        numPrec[t][c][r].y = (int)Math.ceil((try1-cb0y)/twoppy)                            - (int)Math.floor((try0-cb0y)/(double)twoppy);                    } else {                        numPrec[t][c][r].y = 0;                    }                    minsbi = (r==0) ? 0 : 1;                    maxsbi = (r==0) ? 1 : 4;                    cblks[t][c][r] = new CBlkRateDistStats[maxsbi][];                    for(l=0; l<numLayers; l++) {                        truncIdxs[t][l][c][r] = new int[maxsbi][];                    }                    for(s=minsbi; s<maxsbi; s++) { // loop on subbands                        //Get the number of blocks in the current subband                        sb2 = (SubbandAn)sb.getSubbandByIdx(r,s);                        ncblks = sb2.numCb;                        cblkPerSubband = ncblks.x*ncblks.y;                        cblks[t][c][r][s] =                             new CBlkRateDistStats[cblkPerSubband];                                                for(l=0; l<numLayers; l++) {                            truncIdxs[t][l][c][r][s] = new int[cblkPerSubband];                            for(i=0; i<cblkPerSubband; i++) {                                truncIdxs[t][l][c][r][s][i] = -1;                            }                        }                    } // End loop on subbands                } // End lopp on resolution levels            } // End loop on components            if(t!=nt-1) {                src.nextTile();            }        } // End loop on tiles	// Check if encryption is needed for eventual scrambled code-blocks	String str = pl.getParameter("Sprivate_key");	if(str!=null) {	    StringTokenizer stk = new StringTokenizer(str);	    if(stk.countTokens()==2) {		rsaExp = new BigInteger(stk.nextToken());		rsaMod = new BigInteger(stk.nextToken());		BigInteger mOne = new BigInteger("-1");		if(rsaExp.equals(mOne) || rsaMod.equals(mOne)) {		    isEncryptionNeeded = false;		} else {		    isEncryptionNeeded = true;		}	    }	}                //Initialize the packet encoder        pktEnc = new PktEncoder(src,encSpec,numPrec,pl);        // The layers array has to be initialized after the constructor since        // it is needed that the bit stream header has been entirely written    }    /**     * Prints the timing information, if collected, and calls 'finalize' on     * the super class.     * */    public void finalize() throws Throwable {        if(DO_TIMING) {            StringBuffer sb;            sb = new StringBuffer("EBCOTRateAllocator wall clock times:\n");            sb.append("  initialization: ");            sb.append(initTime);            sb.append(" ms\n");            sb.append("  layer building: ");            sb.append(buildTime);            sb.append(" ms\n");            sb.append("  final writing:  ");            sb.append(writeTime);            sb.append(" ms");            FacilityManager.getMsgLogger().                printmsg(MsgLogger.INFO,sb.toString());        }        super.finalize();    }    /**     * Runs the rate allocation algorithm and writes the data to the bit     * stream writer object provided to the constructor.     * */    public void runAndWrite() throws IOException {        //Now, run the rate allocation        buildAndWriteLayers();    }    /**     * 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 void initialize() throws IOException {        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.getNumComps();        int numLvls;        int avgPktLen;                long stime = 0L;        // 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.currentTimeMillis();        // 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(((String)encSpec.sops.getTileDef(t)).equalsIgnoreCase("on")) {                avgPktLen += Markers.SOP_LENGTH;            }            // Add EPH length if set            if(((String)encSpec.ephs.getTileDef(t)).equalsIgnoreCase("on")) {                avgPktLen += 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 += numLayers*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 += numLayers*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.getLength();        np = src.getImgWidth()*src.getImgHeight()/8f;        // SOT marker must be taken into account        for(int t=0; t<numTiles; t++) {            headEnc.reset();            headEnc.encodeTilePartHeader(0,t);            ho += headEnc.getLength();        }	// Seeds of scrambled code-blocks	ho += cblkProtOver;	estimHeadOver = ho;        layers = new EBCOTLayer[numLayers];        for (n = numLayers-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<numLayers-1) {            // At an optimized layer            basebytes = Math.floor(lyrSpec.getTargetBitrate(i)*np);            if(i < lyrSpec.getNOptPoints()-1) {                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 = Math.exp(Math.log((double)nextbytes/basebytes)/loopnlyrs);            layers[n].optimize = true;            for(l=0; l<loopnlyrs; l++) {                newbytes = (int)basebytes - lastbytes - ho;                if(newbytes<minlsz) {  // Skip layer (too small)                    basebytes *= ls;                    numLayers--;                    continue;                }                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 = numLayers-2;        nextbytes = (int) (lyrSpec.getTotBitrate()*np) - ho;        newbytes = nextbytes - ((n>=0) ? layers[n].maxBytes : 0);        while(newbytes<minlsz) {            if(numLayers==1) {                if(newbytes<=0) {                    throw new                        IllegalArgumentException("Overall target bitrate too "+                                                 "low, given the current "+                                                 "bit stream header overhead");                }                break;            }            // Delete last layer            numLayers--;            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;	prog1 = (Progression[])encSpec.pocs.getDefault();	int nValidProg = prog1.length;	for(int prg=0; prg<prog1.length; prg++) {	    if(prog1[prg].lye>numLayers){		prog1[prg].lye = numLayers;	    }	}	if(nValidProg==0) {	    throw new Error("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>numLayers) {			prog1[prg].lye = numLayers;		    }		}		if(nValidProg==0) {		    throw new Error("Unable to initialize rate allocator:"+                                    " No default progression type has been "+                                    "defined for tile "+t);                }	    }	} // End loop on tiles        if(DO_TIMING) initTime += System.currentTimeMillis()-stime;    }    /**     * This method gets all the coded code-blocks from the EBCOT entropy coder     * for every component and every tile. Each coded code-block is stored in     * a 5D array according to the component, the resolution level, the tile,     * the subband it belongs and its position in the subband.     *     * <P> For each code-block, the valid slopes are computed and converted     * into the mantissa-exponent representation.     * */      private void getAllCodeBlocks() {        int numComps, numTiles, numBytes;        int c, r, t, s, sidx, k;        int slope;        SubbandAn subb;        CBlkRateDistStats ccb = null;        Coord ncblks = null;        int last_sidx;        float fslope;        long stime = 0L;        maxSlope = 0f;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?