📄 filebitstreamreaderagent.java
字号:
anbytes = 0; } strInfo += "Main header length : "+cdstreamStart+", "+mainHeadLen+ ", "+mainHeadLen+"\n"; // If cannot even read the first tile-part if(anbytes>tnbytes) { throw new Error("Requested bitrate is too small."); } // Read all tile-part headers from all tiles. int tilePartStart; boolean rateReached = false; int mdl; int numtp = 0; totAllTileLen = 0; remainingTileParts = nt; // at least as many tile-parts as tiles int maxTP = nt; // If maximum 1 tile part per tile specified try { while(remainingTileParts!=0) { tilePartStart = in.getPos(); // Read tile-part header try { t = readTilePartHeader(); if(isEOCFound) { // Some tiles are missing but the // codestream is OK break; } tp = tilePartsRead[t]; if(isPsotEqualsZero) { // Psot may equals zero for the // last tile-part: it is assumed that this tile-part // contain all data until EOC tilePartLen[t][tp] = in.length()-2-tilePartStart; } } catch(EOFException e) { firstPackOff[t][tp] = in.length(); throw e; } pos = in.getPos(); // In truncation mode, if target decoding rate is reached in // tile-part header, skips the tile-part and stop reading // unless the ncb and lbody quit condition is in use if(isTruncMode && ncbQuit == -1) { if((pos-cdstreamStart)>tnbytes) { firstPackOff[t][tp] = in.length(); rateReached = true; break; } } // Set tile part position and header length firstPackOff[t][tp] = pos; tilePartHeadLen[t][tp] = (pos-tilePartStart); strInfo += "Tile-part "+tp+" of tile "+t+" : "+tilePartStart +", "+tilePartLen[t][tp]+", "+tilePartHeadLen[t][tp]+"\n"; // Update length counters totTileLen[t] += tilePartLen[t][tp]; totTileHeadLen[t] += tilePartHeadLen[t][tp]; totAllTileLen += tilePartLen[t][tp]; if(isTruncMode) { if(anbytes+tilePartLen[t][tp]>tnbytes) { anbytes += tilePartHeadLen[t][tp]; headLen += tilePartHeadLen[t][tp]; rateReached = true; nBytes[t] += (tnbytes-anbytes); break; } else { anbytes += tilePartHeadLen[t][tp]; headLen += tilePartHeadLen[t][tp]; nBytes[t] += (tilePartLen[t][tp]- tilePartHeadLen[t][tp]); } } else { if(anbytes+tilePartHeadLen[t][tp]>tnbytes) { break; } else { anbytes += tilePartHeadLen[t][tp]; headLen += tilePartHeadLen[t][tp]; } } // If this is first tile-part, remember header length if(tptot==0) firstTilePartHeadLen = tilePartHeadLen[t][tp]; // Go to the beginning of next tile part tilePartsRead[t]++; in.seek(tilePartStart+tilePartLen[t][tp]); remainingTileParts--; maxTP--; tptot++; // If Psot of the current tile-part was equal to zero, it is // assumed that it contains all data until the EOC marker if(isPsotEqualsZero) { if(remainingTileParts!=0) { FacilityManager.getMsgLogger().printmsg (MsgLogger.WARNING,"Some tile-parts have not "+ "been found. The codestream may be corrupted."); } break; } } } catch(EOFException e) { if(printInfo) { FacilityManager.getMsgLogger(). printmsg(MsgLogger.INFO,strInfo); } FacilityManager.getMsgLogger(). printmsg(MsgLogger.WARNING,"Codestream truncated in tile "+t); // Set specified rate to end of file if valid int fileLen = in.length(); if(fileLen<tnbytes) { tnbytes = fileLen; trate = tnbytes*8f/hd.getMaxCompImgWidth()/ hd.getMaxCompImgHeight(); } // Bit-rate allocation if(!isTruncMode) { allocateRate(); } // Update 'res' value once all tile-part headers are read if(pl.getParameter("res")==null) { targetRes = decSpec.dls.getMin(); } else { try { targetRes = pl.getIntParameter("res"); if(targetRes<0) { throw new IllegalArgumentException("Specified negative "+ "resolution level "+ "index: "+targetRes); } } catch(NumberFormatException f) { throw new IllegalArgumentException("Invalid resolution level "+ "index ('-res' option) " + pl.getParameter("res")); } } // Verify reduction in resolution level mdl = decSpec.dls.getMin(); if(targetRes>mdl) { FacilityManager.getMsgLogger(). printmsg(MsgLogger.WARNING, "Specified resolution level ("+targetRes+ ") is larger"+ " than the maximum value. Setting it to "+ mdl +" (maximum value)"); targetRes = mdl; } // Backup nBytes for (int tIdx=0; tIdx<nt; tIdx++) { baknBytes[tIdx] = nBytes[tIdx]; } return; } remainingTileParts = 0; // Update 'res' value once all tile-part headers are read if(pl.getParameter("res") == null) { targetRes = decSpec.dls.getMin(); } else { try { targetRes = pl.getIntParameter("res"); if(targetRes<0) { throw new IllegalArgumentException("Specified negative "+ "resolution level index: "+ targetRes); } } catch(NumberFormatException e) { throw new IllegalArgumentException("Invalid resolution level "+ "index ('-res' option) " + pl.getParameter("res")); } } // Verify reduction in resolution level mdl = decSpec.dls.getMin(); if(targetRes>mdl) { FacilityManager.getMsgLogger(). printmsg(MsgLogger.WARNING, "Specified resolution level ("+targetRes+ ") is larger"+ " than the maximum possible. Setting it to "+ mdl +" (maximum possible)"); targetRes = mdl; } if(printInfo) { FacilityManager.getMsgLogger().printmsg(MsgLogger.INFO,strInfo); } // Check presence of EOC marker is decoding rate not reached or if // this marker has not been found yet if(!isEOCFound && !isPsotEqualsZero) { try { if(!rateReached && !isPsotEqualsZero && in.readShort()!=EOC) { FacilityManager.getMsgLogger(). printmsg(MsgLogger.WARNING,"EOC marker not found. "+ "Codestream is corrupted."); } } catch(EOFException e) { FacilityManager.getMsgLogger(). printmsg(MsgLogger.WARNING,"EOC marker is missing"); } } // Bit-rate allocation if(!isTruncMode) { allocateRate(); } else { // Take EOC into account if rate is not reached if(in.getPos()>=tnbytes) anbytes += 2; } // Backup nBytes for (int tIdx=0; tIdx<nt; tIdx++) { baknBytes[tIdx] = nBytes[tIdx]; if(printInfo) { FacilityManager.getMsgLogger(). println(""+hi.toStringTileHeader(tIdx,tilePartLen[tIdx]. length),2,2); } } } /** * Allocates output bit-rate for each tile in parsing mode: The allocator * simulates the truncation of a virtual layer-resolution progressive * codestream. * */ private void allocateRate() { int stopOff = tnbytes; // In parsing mode, the bitrate is allocated related to each tile's // length in the bit stream // EOC marker's length anbytes += 2; // If there are too few bytes to read the tile part headers throw an // error if(anbytes>stopOff) { throw new Error("Requested bitrate is too small for parsing"); } // Calculate bitrate for each tile int rem = stopOff-anbytes; int totnByte = rem; for(int t=nt-1; t>0; t--) { rem -= nBytes[t]=(int)(totnByte*(totTileLen[t]/totAllTileLen)); } nBytes[0] = rem; } /** * Reads SOT marker segment of the tile-part header and calls related * methods of the HeaderDecoder to read other markers segments. The * tile-part header is entirely read when a SOD marker is encountered. * * @return The tile number of the tile part that was read * */ private int readTilePartHeader() throws IOException { HeaderInfo.SOT ms = hi.getNewSOT(); // SOT marker short marker = in.readShort(); if(marker!=SOT) { if(marker==EOC) { isEOCFound = true; return -1; } else { throw new CorruptedCodestreamException("SOT tag not found "+ "in tile-part start"); } } isEOCFound = false; // Lsot (shall equals 10) int lsot = in.readUnsignedShort(); ms.lsot = lsot; if(lsot!=10) throw new CorruptedCodestreamException("Wrong length for "+ "SOT marker segment: "+ lsot); // Isot int tile = in.readUnsignedShort(); ms.isot = tile; if(tile>65534){ throw new CorruptedCodestreamException("Tile index too high in "+ "tile-part."); } // Psot int psot = in.readInt(); ms.psot = psot; isPsotEqualsZero = (psot!=0) ? false : true; if(psot<0) { throw new NotImplementedError("Tile length larger "+ "than maximum supported"); } // TPsot int tilePart = in.read(); ms.tpsot = tilePart; if( tilePart!=tilePartsRead[tile] || tilePart<0 || tilePart>254 ) { throw new CorruptedCodestreamException("Out of order tile-part"); } // TNsot int nrOfTileParts = in.read(); ms.tnsot = nrOfTileParts; hi.sot.put("t"+tile+"_tp"+tilePart,ms);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -