ebcotrateallocator.java

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

JAVA
1,684
字号
        minSlope = Float.MAX_VALUE;        //Get the number of components and tiles        numComps = src.getNumComps();        numTiles = src.getNumTiles();	SubbandAn root,sb;	int cblkToEncode = 0;	int nEncCblk = 0;	ProgressWatch pw = FacilityManager.getProgressWatch();        //Get all coded code-blocks Goto first tile        src.setTile(0,0);        for(t=0; t<numTiles; t++) { //loop on tiles	    nEncCblk = 0;	    cblkToEncode = 0;	    for(c=0; c<numComps; c++) {		root = src.getAnSubbandTree(t,c);		for(r=0; r<=root.resLvl; r++) {		    if(r==0) {			sb = (SubbandAn)root.getSubbandByIdx(0,0);			if(sb!=null) cblkToEncode += sb.numCb.x*sb.numCb.y;		    } else {			sb = (SubbandAn)root.getSubbandByIdx(r,1);			if(sb!=null) cblkToEncode += sb.numCb.x*sb.numCb.y;			sb = (SubbandAn)root.getSubbandByIdx(r,2);			if(sb!=null) cblkToEncode += sb.numCb.x*sb.numCb.y;			sb = (SubbandAn)root.getSubbandByIdx(r,3);			if(sb!=null) cblkToEncode += sb.numCb.x*sb.numCb.y;		    }		}	    }	    if(pw!=null) {		pw.initProgressWatch(0,cblkToEncode,"Encoding tile "+t+"...");	    }            for(c=0; c<numComps; c++) { //loop on components                //Get next coded code-block coordinates                while( (ccb=src.getNextCodeBlock(c,ccb)) != null) {                    if(DO_TIMING) stime = System.currentTimeMillis();		    if(pw!=null) {			nEncCblk++;			pw.updateProgressWatch(nEncCblk,null);		    }		                        subb = ccb.sb;		    if(ccb.scrambled) {			cblkProtOver += Scrambling.MIN_SIDE_INFO_LEN;			if(ccb.scramblingType==ScramblingTypes.			   COMP_DOMAIN_SCRAMBLING) {			    cblkProtOver += 2;			}			if((ccb.seed&0xff)==0xff) {			    cblkProtOver += 1;			}			if(isEncryptionNeeded) {			    cblkProtOver += (rsaMod.bitLength()+7)/8;			} else {			    cblkProtOver += 4; // Encode an integer			}		    }                    //Get the coded code-block resolution level index                    r = subb.resLvl;                    //Get the coded code-block subband index                    s = subb.sbandIdx;                    //Get the number of blocks in the current subband                    ncblks = subb.numCb;                    // Add code-block contribution to summary R-D table                    // RDSlopesRates                    last_sidx = -1;                    for(k=ccb.nVldTrunc-1; k>=0; k--) {                        fslope = ccb.truncSlopes[k];                        if(fslope>maxSlope) maxSlope = fslope;                        if(fslope<minSlope) minSlope = fslope;                        sidx = getLimitedSIndexFromSlope(fslope);                        for(; sidx>last_sidx; sidx--) {                            RDSlopesRates[sidx] +=                                ccb.truncRates[ccb.truncIdxs[k]];                        }                        last_sidx = getLimitedSIndexFromSlope(fslope);                    }                    //Fills code-blocks array                    cblks[t][c][r][s][(ccb.m*ncblks.x)+ccb.n] = ccb;                    ccb = null;                    if(DO_TIMING) initTime += System.currentTimeMillis()-stime;                }            }	    	    if(pw!=null) {		pw.terminateProgressWatch();	    }            //Goto next tile            if(t<numTiles-1) { //not at last tile                src.nextTile();	    }        }    }        /**     * This method builds all the bit stream layers and then writes them to     * the output bit stream. Firstly it builds all the layers by computing     * the threshold according to the layer target bit-rate, and then it     * writes the layer bit streams according to the progressive type.     * */      private void buildAndWriteLayers() throws IOException {        int nPrec = 0;        int maxBytes, actualBytes;        float rdThreshold;        SubbandAn sb;        float threshold;        BitOutputBuffer hBuff = null;        byte[] bBuff = null;        int[] tileLengths; // Length of each tile        int tmp;        boolean sopUsed; // Should SOP markers be used ?        boolean ephUsed; // Should EPH markers be used ?        int nc = src.getNumComps();        int nt = src.getNumTiles();        int mrl;        long stime = 0L;        if(DO_TIMING) stime = System.currentTimeMillis();        // Start with the maximum slope        rdThreshold = maxSlope;        tileLengths = new int[nt];        actualBytes = 0;	// +------------------------------+	// |  First we build the layers   |	// +------------------------------+	// Bit stream is simulated to know tile length	for(int l=0; l<numLayers; l++) { // loop on layers	    maxBytes = layers[l].maxBytes;	    if(layers[l].optimize) {		rdThreshold = 		    optimizeBitstreamLayer(l,rdThreshold,maxBytes,actualBytes);	    } else {		if(l<=0 || l>=numLayers-1) {		    throw new IllegalArgumentException("The first and the "+						       "last layer thresholds"+						       " must be optimized");                }		rdThreshold = estimateLayerThreshold(maxBytes,layers[l-1]);	    }	    for(int t=0; t<nt; t++) { // loop on tiles		if(l==0) {		    // Tile header		    headEnc.reset();		    headEnc.encodeTilePartHeader(0,t);		    tileLengths[t] += headEnc.getLength();		}		for(int c=0; c<nc; c++) { //loop on components		    		    // set boolean sopUsed here (SOP markers)		    sopUsed = ((String)encSpec.sops.getTileDef(t)).			equalsIgnoreCase("on");		    // set boolean ephUsed here (EPH markers)		    ephUsed = ((String)encSpec.ephs.getTileDef(t)).			equalsIgnoreCase("on");		    		    // Go to LL band		    sb = src.getAnSubbandTree(t,c);                    mrl = sb.resLvl+1;		    while (sb.subb_LL!=null) sb = sb.subb_LL;		    for(int r=0; r<mrl ; r++) { // loop on resolution levels                        nPrec = numPrec[t][c][r].x*numPrec[t][c][r].y;                        for(int p=0; p<nPrec; p++) { // loop on precincts                            findTruncIndices(l,c,r,t,sb,rdThreshold,p);				                                hBuff = pktEnc.				encodePacket(l+1,c,r,t,cblks[t][c][r], 					     truncIdxs[t][l][c][r],					     hBuff,bBuff,p);                            if(pktEnc.isPacketWritable()) {                                tmp = bsWriter.                                    writePacketHead(hBuff.getBuffer(),                                                    hBuff.getLength(),                                                     true, sopUsed,ephUsed);                                tmp += bsWriter.                                    writePacketBody(pktEnc.getLastBodyBuf(),                                                      pktEnc.getLastBodyLen(),                                                     true,pktEnc.isROIinPkt(),                                                    pktEnc.getROILen());                                actualBytes += tmp;                                tileLengths[t] += tmp;                            }                        } // End loop on precincts			sb = sb.parent;		    } // End loop on resolution levels		} // End loop on components	    } // end loop on tiles	    layers[l].rdThreshold = rdThreshold;	    layers[l].actualBytes = actualBytes;	} // end loop on layers		// Find layer index from which to secure	int secNb = (int)(secBr*src.getImgHeight()*src.getImgWidth()/8.0)-	    estimHeadOver;// 	System.out.println("secNb="+secNb+", estimHeadOver="+estimHeadOver);	secLyStart = numLayers;	for(int l=0; l<numLayers; l++) {// 	    System.out.println("Layer "+l+": "+layers[l].actualBytes);	    if(layers[l].actualBytes>secNb) {		secLyStart = l;		break;	    }	}	// Scramble needed layers 	pktEnc.scrambleLayersFrom(secLyStart,numLayers,				  cblks,truncIdxs,numPrec);	// Add termination segments to scrambled code-blocks	pktEnc.addSecureTermination(numLayers-1,cblks,numPrec);	// +----------------------------+	// | Recompute the tile lengths |	// +----------------------------+	pktEnc.reset();	for(int t=0; t<nt; t++) tileLengths[t] = 0;	for(int l=0; l<numLayers; l++) { // loop on layers	    rdThreshold = layers[l].rdThreshold;	    for(int t=0; t<nt; t++) { // loop on tiles		if(l==0) {		    // Tile header		    headEnc.reset();		    headEnc.encodeTilePartHeader(0,t);		    tileLengths[t] += headEnc.getLength();		}		for(int c=0; c<nc; c++) { //loop on components		    		    // set boolean sopUsed here (SOP markers)		    sopUsed = ((String)encSpec.sops.getTileDef(t)).			equalsIgnoreCase("on");		    // set boolean ephUsed here (EPH markers)		    ephUsed = ((String)encSpec.ephs.getTileDef(t)).			equalsIgnoreCase("on");		    		    // Go to LL band		    sb = src.getAnSubbandTree(t,c);                    mrl = sb.resLvl+1;		    while (sb.subb_LL!=null) sb = sb.subb_LL;		    for(int r=0; r<mrl ; r++) { // loop on resolution levels                        nPrec = numPrec[t][c][r].x*numPrec[t][c][r].y;                        for(int p=0; p<nPrec; p++) { // loop on precincts                            findTruncIndices(l,c,r,t,sb,rdThreshold,p);				                                hBuff = pktEnc.				encodePacket(l+1,c,r,t,cblks[t][c][r], 					     truncIdxs[t][l][c][r],					     hBuff,bBuff,p);                            if(pktEnc.isPacketWritable()) {                                tmp = bsWriter.                                    writePacketHead(hBuff.getBuffer(),                                                    hBuff.getLength(),                                                     true, sopUsed,ephUsed);                                tmp += bsWriter.                                    writePacketBody(pktEnc.getLastBodyBuf(),                                                      pktEnc.getLastBodyLen(),                                                     true,pktEnc.isROIinPkt(),                                                    pktEnc.getROILen());                                actualBytes += tmp;                                tileLengths[t] += tmp;                            }                        } // End loop on precincts			sb = sb.parent;		    } // End loop on resolution levels		} // End loop on components	    } // end loop on tiles	    layers[l].rdThreshold = rdThreshold;	    layers[l].actualBytes = actualBytes;	} // end loop on layers	// +----------------------------+	        if(DO_TIMING) buildTime += System.currentTimeMillis()-stime;	// The bit-stream was not yet generated (only simulated).        if(DO_TIMING) stime = System.currentTimeMillis();	// +--------------------------------------------------+	// | Write tiles according to their Progression order |	// +--------------------------------------------------+	// Reset the packet encoder before writing all packets	pktEnc.reset();	Progression[] prog; // Progression(s) in each tile	int cs,ce,rs,re,lye;        int[] mrlc = new int[nc];	for(int t=0; t<nt; t++) { //loop on tiles	    int[][] lysA; // layer index start for each component and	    // resolution level	    int[][] lys = new int[nc][];	    for(int c=0; c<nc; c++) {                mrlc[c] = src.getAnSubbandTree(t,c).resLvl;		lys[c] = new int[mrlc[c]+1];	    }	    	    // Tile header	    headEnc.reset();	    headEnc.encodeTilePartHeader(tileLengths[t],t);	    bsWriter.commitBitstreamHeader(headEnc);	    prog = (Progression[])encSpec.pocs.getTileDef(t);	    for(int prg=0; prg<prog.length;prg++) { // Loop on progression		lye = prog[prg].lye;		cs = prog[prg].cs;		ce = prog[prg].ce;		rs = prog[prg].rs;		re = prog[prg].re;		switch(prog[prg].type) {		case ProgressionType.RES_LY_COMP_POS_PROG:

⌨️ 快捷键说明

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