All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jj2000.j2k.codestream.writer.PktEncoder Maven / Gradle / Ivy

Go to download

JPEG2000 support for Java Advanced Imaging Image I/O Tools API core. This module is licensed under the [JJ2000 license](LICENSE.txt) and is therefore NOT compatible with the GPL 3 license. It should be compatible with the LGPL 2.1 license.

There is a newer version: 1.4.0
Show newest version
/*
 * $RCSfile: PktEncoder.java,v $
 * $Revision: 1.1 $
 * $Date: 2005/02/11 05:02:03 $
 * $State: Exp $
 *
 * Class:                   PktEncoder
 *
 * Description:             Builds bit stream packets and keeps
 *                          interpacket dependencies.
 *
 *
 *
 * COPYRIGHT:
 *
 * This software module was originally developed by Raphaël Grosbois and
 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
 * Centre France S.A) in the course of development of the JPEG2000
 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
 * software module is an implementation of a part of the JPEG 2000
 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
 * Systems AB and Canon Research Centre France S.A (collectively JJ2000
 * Partners) agree not to assert against ISO/IEC and users of the JPEG
 * 2000 Standard (Users) any of their rights under the copyright, not
 * including other intellectual property rights, for this software module
 * with respect to the usage by ISO/IEC and Users of this software module
 * or modifications thereof for use in hardware or software products
 * claiming conformance to the JPEG 2000 Standard. Those intending to use
 * this software module in hardware or software products are advised that
 * their use may infringe existing patents. The original developers of
 * this software module, JJ2000 Partners and ISO/IEC assume no liability
 * for use of this software module or modifications thereof. No license
 * or right to this software module is granted for non JPEG 2000 Standard
 * conforming products. JJ2000 Partners have full right to use this
 * software module for his/her own purpose, assign or donate this
 * software module to any third party and to inhibit third parties from
 * using this software module for non JPEG 2000 Standard conforming
 * products. This copyright notice must be included in all copies or
 * derivative works of this software module.
 *
 * Copyright (c) 1999/2000 JJ2000 Partners.
 * */

package jj2000.j2k.codestream.writer;
import java.awt.Point;
import java.util.Vector;

import jj2000.j2k.codestream.CBlkCoordInfo;
import jj2000.j2k.codestream.PrecInfo;
import jj2000.j2k.entropy.encoder.CBlkRateDistStats;
import jj2000.j2k.entropy.encoder.CodedCBlkDataSrcEnc;
import jj2000.j2k.util.ArrayUtil;
import jj2000.j2k.util.MathUtil;
import jj2000.j2k.wavelet.analysis.SubbandAn;

import com.github.jaiimageio.jpeg2000.impl.J2KImageWriteParamJava;
/**
 * This class builds packets and keeps the state information of packet
 * interdependencies. It also supports saving the state and reverting
 * (restoring) to the last saved state, with the save() and restore() methods.
 *
 * 

Each time the encodePacket() method is called a new packet is encoded, * the packet header is returned by the method, and the packet body can be * obtained with the getLastBodyBuf() and getLastBodyLen() methods. * */ public class PktEncoder { /** The prefix for packet encoding options: 'P' */ public final static char OPT_PREFIX = 'P'; /** The list of parameters that is accepted for packet encoding.*/ private final static String [][] pinfo = { { "Psop", "[] true|false"+ "[ [] true|false ...]", "Specifies whether start of packet (SOP) markers should be used. "+ "'true' enables, 'false' disables it.","false"}, { "Peph", "[] true|false"+ "[ [] true|false ...]", "Specifies whether end of packet header (EPH) markers should be "+ " used. 'true' enables, 'false' disables it.","false"} }; /** The initial value for the lblock */ private final static int INIT_LBLOCK = 3; /** The source object */ private CodedCBlkDataSrcEnc infoSrc; /** The encoder specs */ J2KImageWriteParamJava wp; /** * The tag tree for inclusion information. The indexes are outlined * below. Note that the layer indexes start at 1, therefore, the layer * index minus 1 is used. The subband indices are used as they are defined * in the Subband class. The tile indices start at 0 and follow a * lexicographical order. * *

    *
  • 1st index: tile index, in lexicographical order
  • *
  • 2nd index: component index
  • *
  • 3rd index: resolution level
  • *
  • 4th index: subband index
  • *
  • 5th index: precinct index
  • *
**/ private TagTreeEncoder ttIncl[][][][][]; /** * The tag tree for the maximum significant bit-plane. The indexes are * outlined below. Note that the layer indexes start at 1, therefore, the * layer index minus 1 is used. The subband indices are used as they are * defined in the Subband class. The tile indices start at 0 and follow a * lexicographical order. * *
    *
  • 1st index: tile index, in lexicographical order
  • *
  • 2nd index: component index
  • *
  • 3rd index: resolution level
  • *
  • 4th index: subband index - subband index offset
  • *
  • 5th index: precinct index
  • *
* */ private TagTreeEncoder ttMaxBP[][][][][]; /** * The base number of bits for sending code-block length information * (referred as Lblock in the JPEG 2000 standard). The indexes are * outlined below. Note that the layer indexes start at 1, therefore, the * layer index minus 1 is used. The subband indices are used as they are * defined in the Subband class. The tile indices start at 0 and follow a * lexicographical order. * *
    *
  • 1st index: tile index, in lexicographical order
  • *
  • 2nd index: component index
  • *
  • 3rd index: resolution level
  • *
  • 4th index: subband index - subband index offset
  • *
  • 5th index: code-block index, in lexicographical order
  • *
* */ private int lblock[][][][][]; /** * The last encoded truncation point for each code-block. A negative value * means that no information has been included for the block, yet. The * indexes are outlined below. The subband indices are used as they are * defined in the Subband class. The tile indices start at 0 and follow a * lexicographical order. The code-block indices follow a lexicographical * order within the subband tile. * *

What is actually stored is the index of the element in * CBlkRateDistStats.truncIdxs that gives the real truncation point. * *

    *
  • 1st index: tile index, in lexicographical order
  • *
  • 2nd index: component index
  • *
  • 3rd index: resolution level
  • *
  • 4th index: subband index - subband index offset
  • *
  • 5th index: code-block index, in lexicographical order
  • *
* */ private int prevtIdxs[][][][][]; /** * The saved base number of bits for sending code-block length * information. It is used for restoring previous saved state by * restore(). The indexes are outlined below. Note that the layer indexes * start at 1, therefore, the layer index minus 1 is used. The subband * indices are used as they are defined in the Subband class. The tile * indices start at 0 and follow a lexicographical order. * *
    *
  • 1st index: tile index, in lexicographical order
  • *
  • 2nd index: component index
  • *
  • 3rd index: resolution level
  • *
  • 4th index: subband index - subband index offset
  • *
  • 5th index: code-block index, in lexicographical order
  • *
* */ private int bak_lblock[][][][][]; /** * The saved last encoded truncation point for each code-block. It is used * for restoring previous saved state by restore(). A negative value means * that no information has been included for the block, yet. The indexes * are outlined below. The subband indices are used as they are defined in * the Subband class. The tile indices start at 0 and follow a * lexicographical order. The code-block indices follow a lexicographical * order within the subband tile. * *
    *
  • 1st index: tile index, in lexicographical order
  • *
  • 2nd index: component index
  • *
  • 3rd index: resolution level
  • *
  • 4th index: subband index - subband index offset
  • *
  • 5th index: code-block index, in lexicographical order
  • *
* */ private int bak_prevtIdxs[][][][][]; /** The body buffer of the last encoded packet */ private byte[] lbbuf; /** The body length of the last encoded packet */ private int lblen; /** The saved state */ private boolean saved; /** Whether or not there is ROI information in the last encoded Packet */ private boolean roiInPkt = false; /** Length to read in current packet body to get all the ROI information */ private int roiLen = 0; /** * Array containing the coordinates, width, height, indexes, ... of the * precincts. * *
    *
  • 1st dim: tile index.
  • *
  • 2nd dim: component index.
  • *
  • 3rd dim: resolution level index.
  • *
  • 4th dim: precinct index.
  • *
* */ private PrecInfo ppinfo[][][][]; /** Whether or not the current packet is writable */ private boolean packetWritable; /** * Creates a new packet header encoder, using the information from the * 'infoSrc' object. The information used is the number of components, * number of tiles, subband decomposition, etc. * *

Note that this constructor visits all the tiles in the 'infoSrc' * object. The 'infoSrc' object is left at the original tile (i.e. the * current tile before calling this constructor), but any side effects of * visiting the tiles is not reverted. * * @param infoSrc The source of information to construct the * object. * * @param encSpec The parameters for the encoding * * @param maxNumPrec Maximum number of precinct in each tile, component * and resolution level. * * @param pl ParameterList instance that holds command line options * */ public PktEncoder(CodedCBlkDataSrcEnc infoSrc, J2KImageWriteParamJava wp, Point[][][] numPrec) { this.infoSrc = infoSrc; this.wp = wp; // this.numPrec = numPrec; // Get number of components and tiles int nc = infoSrc.getNumComps(); int nt = infoSrc.getNumTiles(); // Do initial allocation ttIncl = new TagTreeEncoder[nt][nc][][][]; ttMaxBP = new TagTreeEncoder[nt][nc][][][]; lblock = new int[nt][nc][][][]; prevtIdxs = new int[nt][nc][][][]; ppinfo = new PrecInfo[nt][nc][][]; // Finish allocation SubbandAn root,sb; int maxs,mins; int mrl; Point tmpCoord = null; int numcb; // Number of code-blocks Vector cblks = null; infoSrc.setTile(0,0); for (int t=0; tsb.ulcx+sb.w) ? sb.ulcx+sb.w : p1x; s0y = (p0ysb.ulcy+sb.h) ? sb.ulcy+sb.h : p1y; // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch) cw = sb.nomCBlkW; ch = sb.nomCBlkH; k0 = (int)Math.floor((sb.ulcy-acb0y)/(double)ch); kstart = (int)Math.floor((s0y-acb0y)/(double)ch); kend = (int)Math.floor((s1y-1-acb0y)/(double)ch); l0 = (int)Math.floor((sb.ulcx-acb0x)/(double)cw); lstart = (int)Math.floor((s0x-acb0x)/(double)cw); lend = (int)Math.floor((s1x-1-acb0x)/(double)cw); if(s1x-s0x<=0 || s1y-s0y<=0) { ppinfo[t][c][r][nPrec].nblk[0] = 0; ttIncl[t][c][r][nPrec][0] = new TagTreeEncoder(0,0); ttMaxBP[t][c][r][nPrec][0] = new TagTreeEncoder(0,0); } else { ttIncl[t][c][r][nPrec][0] = new TagTreeEncoder(kend-kstart+1,lend-lstart+1); ttMaxBP[t][c][r][nPrec][0] = new TagTreeEncoder(kend-kstart+1,lend-lstart+1); ppinfo[t][c][r][nPrec].cblk[0] = new CBlkCoordInfo[kend-kstart+1][lend-lstart+1]; ppinfo[t][c][r][nPrec]. nblk[0] = (kend-kstart+1)*(lend-lstart+1); for(int k=kstart; k<=kend; k++) { // Vertical cblks for(int l=lstart; l<=lend; l++) { // Horiz. cblks cb = new CBlkCoordInfo(k-k0,l-l0); ppinfo[t][c][r][nPrec]. cblk[0][k-kstart][l-lstart] = cb; } // Horizontal code-blocks } // Vertical code-blocks } } else { // HL, LH and HH subbands // HL subband acb0x = 0; acb0y = cb0y; p0x = acb0x+j*twoppx2; p1x = p0x + twoppx2; p0y = acb0y+i*twoppy2; p1y = p0y + twoppy2; sb = (SubbandAn)root.getSubbandByIdx(r,1); s0x = (p0xsb.ulcx+sb.w) ? sb.ulcx+sb.w : p1x; s0y = (p0ysb.ulcy+sb.h) ? sb.ulcy+sb.h : p1y; // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch) cw = sb.nomCBlkW; ch = sb.nomCBlkH; k0 = (int)Math.floor((sb.ulcy-acb0y)/(double)ch); kstart = (int)Math.floor((s0y-acb0y)/(double)ch); kend = (int)Math.floor((s1y-1-acb0y)/(double)ch); l0 = (int)Math.floor((sb.ulcx-acb0x)/(double)cw); lstart = (int)Math.floor((s0x-acb0x)/(double)cw); lend = (int)Math.floor((s1x-1-acb0x)/(double)cw); if(s1x-s0x<=0 || s1y-s0y<=0) { ppinfo[t][c][r][nPrec].nblk[1] = 0; ttIncl[t][c][r][nPrec][1] = new TagTreeEncoder(0,0); ttMaxBP[t][c][r][nPrec][1] = new TagTreeEncoder(0,0); } else { ttIncl[t][c][r][nPrec][1] = new TagTreeEncoder(kend-kstart+1,lend-lstart+1); ttMaxBP[t][c][r][nPrec][1] = new TagTreeEncoder(kend-kstart+1,lend-lstart+1); ppinfo[t][c][r][nPrec].cblk[1] = new CBlkCoordInfo[kend-kstart+1][lend-lstart+1]; ppinfo[t][c][r][nPrec]. nblk[1] = (kend-kstart+1)*(lend-lstart+1); for(int k=kstart; k<=kend; k++) { // Vertical cblks for(int l=lstart; l<=lend; l++) { // Horiz. cblks cb = new CBlkCoordInfo(k-k0,l-l0); ppinfo[t][c][r][nPrec]. cblk[1][k-kstart][l-lstart] = cb; } // Horizontal code-blocks } // Vertical code-blocks } // LH subband acb0x = cb0x; acb0y = 0; p0x = acb0x+j*twoppx2; p1x = p0x + twoppx2; p0y = acb0y+i*twoppy2; p1y = p0y + twoppy2; sb = (SubbandAn)root.getSubbandByIdx(r,2); s0x = (p0xsb.ulcx+sb.w) ? sb.ulcx+sb.w : p1x; s0y = (p0ysb.ulcy+sb.h) ? sb.ulcy+sb.h : p1y; // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch) cw = sb.nomCBlkW; ch = sb.nomCBlkH; k0 = (int)Math.floor((sb.ulcy-acb0y)/(double)ch); kstart = (int)Math.floor((s0y-acb0y)/(double)ch); kend = (int)Math.floor((s1y-1-acb0y)/(double)ch); l0 = (int)Math.floor((sb.ulcx-acb0x)/(double)cw); lstart = (int)Math.floor((s0x-acb0x)/(double)cw); lend = (int)Math.floor((s1x-1-acb0x)/(double)cw); if(s1x-s0x<=0 || s1y-s0y<=0) { ppinfo[t][c][r][nPrec].nblk[2] = 0; ttIncl[t][c][r][nPrec][2] = new TagTreeEncoder(0,0); ttMaxBP[t][c][r][nPrec][2] = new TagTreeEncoder(0,0); } else { ttIncl[t][c][r][nPrec][2] = new TagTreeEncoder(kend-kstart+1,lend-lstart+1); ttMaxBP[t][c][r][nPrec][2] = new TagTreeEncoder(kend-kstart+1,lend-lstart+1); ppinfo[t][c][r][nPrec].cblk[2] = new CBlkCoordInfo[kend-kstart+1][lend-lstart+1]; ppinfo[t][c][r][nPrec]. nblk[2] = (kend-kstart+1)*(lend-lstart+1); for(int k=kstart; k<=kend; k++) { // Vertical cblks for(int l=lstart; l<=lend; l++) { // Horiz cblks cb = new CBlkCoordInfo(k-k0,l-l0); ppinfo[t][c][r][nPrec]. cblk[2][k-kstart][l-lstart] = cb; } // Horizontal code-blocks } // Vertical code-blocks } // HH subband acb0x = 0; acb0y = 0; p0x = acb0x+j*twoppx2; p1x = p0x + twoppx2; p0y = acb0y+i*twoppy2; p1y = p0y + twoppy2; sb = (SubbandAn)root.getSubbandByIdx(r,3); s0x = (p0xsb.ulcx+sb.w) ? sb.ulcx+sb.w : p1x; s0y = (p0ysb.ulcy+sb.h) ? sb.ulcy+sb.h : p1y; // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch) cw = sb.nomCBlkW; ch = sb.nomCBlkH; k0 = (int)Math.floor((sb.ulcy-acb0y)/(double)ch); kstart = (int)Math.floor((s0y-acb0y)/(double)ch); kend = (int)Math.floor((s1y-1-acb0y)/(double)ch); l0 = (int)Math.floor((sb.ulcx-acb0x)/(double)cw); lstart = (int)Math.floor((s0x-acb0x)/(double)cw); lend = (int)Math.floor((s1x-1-acb0x)/(double)cw); if(s1x-s0x<=0 || s1y-s0y<=0) { ppinfo[t][c][r][nPrec].nblk[3] = 0; ttIncl[t][c][r][nPrec][3] = new TagTreeEncoder(0,0); ttMaxBP[t][c][r][nPrec][3] = new TagTreeEncoder(0,0); } else { ttIncl[t][c][r][nPrec][3] = new TagTreeEncoder(kend-kstart+1,lend-lstart+1); ttMaxBP[t][c][r][nPrec][3] = new TagTreeEncoder(kend-kstart+1,lend-lstart+1); ppinfo[t][c][r][nPrec].cblk[3] = new CBlkCoordInfo[kend-kstart+1][lend-lstart+1]; ppinfo[t][c][r][nPrec]. nblk[3] = (kend-kstart+1)*(lend-lstart+1); for(int k=kstart; k<=kend; k++) { // Vertical cblks for(int l=lstart; l<=lend; l++) { // Horiz cblks cb = new CBlkCoordInfo(k-k0,l-l0); ppinfo[t][c][r][nPrec]. cblk[3][k-kstart][l-lstart] = cb; } // Horizontal code-blocks } // Vertical code-blocks } } } // Horizontal precincts } // Vertical precincts } /** * Encodes a packet and returns the buffer containing the encoded packet * header. The code-blocks appear in a 3D array of CBlkRateDistStats, * 'cbs'. The first index is the tile index in lexicographical order, the * second index is the subband index (as defined in the Subband class), * and the third index is the code-block index (whithin the subband tile) * in lexicographical order as well. The indexes of the new truncation * points for each code-block are specified by the 3D array of int * 'tIndx'. The indices of this array are the same as for cbs. The * truncation point indices in 'tIndx' are the indices of the elements of * the 'truncIdxs' array, of the CBlkRateDistStats class, that give the * real truncation points. If a truncation point index is negative it * means that the code-block has not been included in any layer yet. If * the truncation point is less than or equal to the highest truncation * point used in previous layers then the code-block is not included in * the packet. Otherwise, if larger, the code-block is included in the * packet. The body of the packet can be obtained with the * getLastBodyBuf() and getLastBodyLen() methods. * *

Layers must be coded in increasing order, in consecutive manner, for * each tile, component and resolution level (e.g., layer 1, then layer 2, * etc.). For different tile, component and/or resolution level no * particular order must be followed.

* * @param ly The layer index (starts at 1). * * @param c The component index. * * @param r The resolution level * * @param t Index of the current tile * * @param cbs The 3D array of coded code-blocks. * * @param tIndx The truncation point indices for each code-block. * * @param hbuf The header buffer. If null a new BitOutputBuffer is created * and returned. This buffer is reset before anything is written to it. * * @param bbuf The body buffer. If null a new one is created. If not large * enough a new one is created. * * @param pIdx The precinct index. * * @return The buffer containing the packet header. * */ public BitOutputBuffer encodePacket(int ly,int c,int r,int t, CBlkRateDistStats cbs[][], int tIndx[][],BitOutputBuffer hbuf, byte bbuf[],int pIdx) { int b,i,maxi; int ncb; int thmax; int newtp; int cblen; int prednbits,nbits,deltabits; TagTreeEncoder cur_ttIncl,cur_ttMaxBP; // inclusion and bit-depth tag // trees int cur_prevtIdxs[]; // last encoded truncation points CBlkRateDistStats cur_cbs[]; int cur_tIndx[]; // truncation points to encode int minsb = (r==0) ? 0 : 1; int maxsb = (r==0) ? 1 : 4; Point cbCoord = null; SubbandAn root = infoSrc.getAnSubbandTree(t,c); SubbandAn sb; roiInPkt = false; roiLen = 0; int mend,nend; // Checks if a precinct with such an index exists in this resolution // level if(pIdx>=ppinfo[t][c][r].length) { packetWritable = false; return hbuf; } PrecInfo prec = ppinfo[t][c][r][pIdx]; // First, we check if packet is empty (i.e precinct 'pIdx' has no // code-block in any of the subbands) boolean isPrecVoid = true; for(int s=minsb; s // stop isPrecVoid = false; break; } } if(isPrecVoid) { packetWritable = true; if(hbuf == null) { hbuf = new BitOutputBuffer(); } else { hbuf.reset(); } if (bbuf == null) { lbbuf = bbuf = new byte[1]; } hbuf.writeBit(0); lblen = 0; return hbuf; } if(hbuf == null) { hbuf = new BitOutputBuffer(); } else { hbuf.reset(); } // Invalidate last body buffer lbbuf = null; lblen = 0; // Signal that packet is present hbuf.writeBit(1); for(int s=minsb; scur_prevtIdxs[b] && cur_prevtIdxs[b]<0) { // First inclusion cur_ttIncl.setValue(m,n,ly-1); } if (ly==1) { // First layer, need to set the skip of MSBP cur_ttMaxBP.setValue(m,n,cur_cbs[b].skipMSBP); } } } // Now encode the information for(int m=0; mcur_prevtIdxs[b]) { // Code-block included in this layer if (cur_prevtIdxs[b]<0) { // First inclusion // Encode layer info cur_ttIncl.encode(m,n,ly,hbuf); // 2) Max bitdepth info. Encode value thmax = cur_cbs[b].skipMSBP+1; for (i=1; i<=thmax; i++) { cur_ttMaxBP.encode(m,n,i,hbuf); } // Count body size for packet lblen += cur_cbs[b]. truncRates[cur_cbs[b].truncIdxs[cur_tIndx[b]]]; } else { // Already in previous layer // Send "1" bit hbuf.writeBit(1); // Count body size for packet lblen += cur_cbs[b]. truncRates[cur_cbs[b]. truncIdxs[cur_tIndx[b]]] - cur_cbs[b]. truncRates[cur_cbs[b]. truncIdxs[cur_prevtIdxs[b]]]; } // 3) Truncation point information if (cur_prevtIdxs[b]<0) { newtp = cur_cbs[b].truncIdxs[cur_tIndx[b]]; } else { newtp = cur_cbs[b].truncIdxs[cur_tIndx[b]]- cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]-1; } // Mix of switch and if is faster switch (newtp) { case 0: hbuf.writeBit(0); // Send one "0" bit break; case 1: hbuf.writeBits(2,2); // Send one "1" and one "0" break; case 2: case 3: case 4: // Send two "1" bits followed by 2 bits // representation of newtp-2 hbuf.writeBits((3<<2)|(newtp-2),4); break; default: if (newtp <= 35) { // Send four "1" bits followed by a five bits // representation of newtp-5 hbuf.writeBits((15<<5)|(newtp-5),9); } else if (newtp <= 163) { // Send nine "1" bits followed by a seven bits // representation of newtp-36 hbuf.writeBits((511<<7)|(newtp-36),16); } else { throw new ArithmeticException("Maximum number "+ "of truncation "+ "points exceeded"); } } } else { // Block not included in this layer if (cur_prevtIdxs[b]>=0) { // Already in previous layer. Send "0" bit hbuf.writeBit(0); } else { // Not in any previous layers cur_ttIncl.encode(m,n,ly,hbuf); } // Go to the next one. continue; } // Code-block length // We need to compute the maximum number of bits needed to // signal the length of each terminated segment and the // final truncation point. newtp = 1; maxi = cur_cbs[b].truncIdxs[cur_tIndx[b]]; cblen = (cur_prevtIdxs[b]<0) ? 0 : cur_cbs[b].truncRates[cur_cbs[b]. truncIdxs[cur_prevtIdxs[b]]]; // Loop on truncation points i = (cur_prevtIdxs[b]<0) ? 0 : cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]+1; int minbits = 0; for (; i0) ? MathUtil.log2(cblen) : 0)+1; // Update Lblock increment if needed for(int j=prednbits; j0) ? MathUtil.log2(cblen) : 0)+1; // Update Lblock increment if needed for(int j=prednbits; j Copy the data to the body buffer // Ensure size for body data if (bbuf==null || bbuf.lengthcur_prevtIdxs[b]) { // Block included in this precinct -> Copy data to // body buffer and get code-size if (cur_prevtIdxs[b]<0) { cblen = cur_cbs[b]. truncRates[cur_cbs[b].truncIdxs[cur_tIndx[b]]]; System.arraycopy(cur_cbs[b].data,0, lbbuf,lblen,cblen); } else { cblen = cur_cbs[b]. truncRates[cur_cbs[b]. truncIdxs[cur_tIndx[b]]] - cur_cbs[b]. truncRates[cur_cbs[b]. truncIdxs[cur_prevtIdxs[b]]]; System. arraycopy(cur_cbs[b].data, cur_cbs[b]. truncRates[cur_cbs[b]. truncIdxs[cur_prevtIdxs [b]]], lbbuf,lblen,cblen); } lblen += cblen; // Verifies if this code-block contains new ROI // information if(cur_cbs[b].nROIcoeff!=0 && (cur_prevtIdxs[b]==-1 || cur_cbs[b].truncIdxs[cur_prevtIdxs[b]] <= cur_cbs[b].nROIcp-1) ) { roiInPkt = true; roiLen = lblen; } // Update truncation point cur_prevtIdxs[b] = cur_tIndx[b]; } } // End loop on horizontal code-blocks } // End loop on vertical code-blocks } // End loop on subbands packetWritable = true; // Must never happen if(hbuf.getLength()==0) { throw new Error("You have found a bug in PktEncoder, method:"+ " encodePacket"); } return hbuf; } /** * Returns the buffer of the body of the last encoded packet. The length * of the body can be retrieved with the getLastBodyLen() method. The * length of the array returned by this method may be larger than the * actual body length. * * @return The buffer of body of the last encoded packet. * * @exception IllegalArgumentException If no packet has been coded since * last reset(), last restore(), or object creation. * * @see #getLastBodyLen * */ public byte[] getLastBodyBuf() { if (lbbuf == null) { throw new IllegalArgumentException(); } return lbbuf; } /** * Returns the length of the body of the last encoded packet, in * bytes. The body itself can be retrieved with the getLastBodyBuf() * method. * * @return The length of the body of last encoded packet, in bytes. * * @see #getLastBodyBuf * */ public int getLastBodyLen() { return lblen; } /** * Saves the current state of this object. The last saved state * can be restored with the restore() method. * * @see #restore * */ public void save() { int maxsbi,minsbi; // Have we done any save yet? if (bak_lblock==null) { // Allocate backup buffers bak_lblock = new int[ttIncl.length][][][][]; bak_prevtIdxs = new int[ttIncl.length][][][][]; for (int t=ttIncl.length-1; t>=0; t--) { bak_lblock[t] = new int[ttIncl[t].length][][][]; bak_prevtIdxs[t] = new int[ttIncl[t].length][][][]; for (int c=ttIncl[t].length-1; c>=0; c--) { bak_lblock[t][c] = new int[lblock[t][c].length][][]; bak_prevtIdxs[t][c] = new int[ttIncl[t][c].length][][]; for (int r=lblock[t][c].length-1; r>=0; r--) { bak_lblock[t][c][r] = new int[lblock[t][c][r].length][]; bak_prevtIdxs[t][c][r] = new int[prevtIdxs[t][c][r].length][]; minsbi = (r==0) ? 0 : 1; maxsbi = (r==0) ? 1 : 4; for (int s=minsbi; s=0; t--) { // Loop on components for (int c=ttIncl[t].length-1; c>=0; c--) { // Initialize reference caches lblock_t_c = lblock[t][c]; bak_lblock_t_c = bak_lblock[t][c]; ttIncl_t_c = ttIncl[t][c]; ttMaxBP_t_c = ttMaxBP[t][c]; // Loop on resolution levels for (int r=lblock_t_c.length-1; r>=0; r--) { // Initialize reference caches ttIncl_t_c_r = ttIncl_t_c[r]; ttMaxBP_t_c_r = ttMaxBP_t_c[r]; prevtIdxs_t_c_r = prevtIdxs[t][c][r]; bak_prevtIdxs_t_c_r = bak_prevtIdxs[t][c][r]; // Loop on subbands minsbi = (r==0) ? 0 : 1; maxsbi = (r==0) ? 1 : 4; for (int s=minsbi; s=0; p--) { if(p=0; t--) { // Loop on components for (int c=ttIncl[t].length-1; c>=0; c--) { // Initialize reference caches lblock_t_c = lblock[t][c]; bak_lblock_t_c = bak_lblock[t][c]; ttIncl_t_c = ttIncl[t][c]; ttMaxBP_t_c = ttMaxBP[t][c]; // Loop on resolution levels for (int r=lblock_t_c.length-1; r>=0; r--) { // Initialize reference caches ttIncl_t_c_r = ttIncl_t_c[r]; ttMaxBP_t_c_r = ttMaxBP_t_c[r]; prevtIdxs_t_c_r = prevtIdxs[t][c][r]; bak_prevtIdxs_t_c_r = bak_prevtIdxs[t][c][r]; // Loop on subbands minsbi = (r==0) ? 0 : 1; maxsbi = (r==0) ? 1 : 4; for (int s=minsbi; s=0; p--) { if(p=0; t--) { // Loop on components for (int c=ttIncl[t].length-1; c>=0; c--) { // Initialize reference caches lblock_t_c = lblock[t][c]; ttIncl_t_c = ttIncl[t][c]; ttMaxBP_t_c = ttMaxBP[t][c]; // Loop on resolution levels for (int r=lblock_t_c.length-1; r>=0; r--) { // Initialize reference caches ttIncl_t_c_r = ttIncl_t_c[r]; ttMaxBP_t_c_r = ttMaxBP_t_c[r]; prevtIdxs_t_c_r = prevtIdxs[t][c][r]; // Loop on subbands minsbi = (r==0) ? 0 : 1; maxsbi = (r==0) ? 1 : 4; for (int s=minsbi; s=0; p--) { if(p




© 2015 - 2024 Weber Informatics LLC | Privacy Policy