codestreammanipulator.java
来自「jpeg2000编解码」· Java 代码 · 共 712 行 · 第 1/2 页
JAVA
712 行
/* * CVS identifier: * * $Id: CodestreamManipulator.java,v 1.1.1.1 2002/07/22 09:26:53 grosbois Exp $ * * Class: CodestreamManipulator * * Description: Manipulates codestream to create tile-parts etc * * * * COPYRIGHT: * * This software module was originally developed by Rapha雔 Grosbois and * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel * Askel鰂 (Ericsson Radio Systems AB); and Bertrand Berthelot, David * Bouchard, F閘ix 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.util;import jj2000.j2k.codestream.*;import jj2000.j2k.io.*;import java.util.*;import java.io.*;/** * This class takes a legal JPEG 2000 codestream and performs some * manipulation on it. Currently the manipulations supported are: Tile-parts * */public class CodestreamManipulator{ /** Flag indicating whether packed packet headers in main header is used * */ private boolean ppmUsed; /** Flag indicating whether packed packet headers in tile headers is used * */ private boolean pptUsed; /** Flag indicating whether SOP marker was only intended for parsing in * This class and should be removed */ private boolean tempSop; /** Flag indicating whether EPH marker was only intended for parsing in * This class and should be removed */ private boolean tempEph; /** The number of tiles in the image */ private int nt; /** The number of packets per tile-part */ private int pptp; /** The name of the outfile */ private String outname; /** The length of a SOT plus a SOD marker */ private static int TP_HEAD_LEN = 14; /** The maximum number of a tile part index (TPsot) */ private static int MAX_TPSOT = 16; /** The maximum number of tile parts in any tile */ private int maxtp; /** The number of packets per tile */ private int[] ppt = new int[nt]; /** The positions of the SOT, SOP and EPH markers */ private Integer[] positions; /** The main header */ private byte[] mainHeader; /** Buffers containing the tile parts */ private byte[][][] tileParts; /** Buffers containing the original tile headers */ private byte[][] tileHeaders; /** Buffers contaning the packet headers */ private byte[][][] packetHeaders; /** Buffers containing the packet data */ private byte[][][] packetData; /** Buffers containing the SOP marker segments */ private byte[][][] sopMarkSeg; /** * Instantiates a codestream manipulator.. * * @param outname The name of the original outfile * * @param nt The number of tiles in the image * * @param pptp Packets per tile-part. If zero, no division into tileparts * is performed * * @param ppm Flag indicating that PPM marker is used * * @param ppt Flag indicating that PPT marker is used * * @param tempSop Flag indicating whether SOP merker should be removed * * @param tempEph Flag indicating whether EPH merker should be removed * */ public CodestreamManipulator(String outname, int nt, int pptp, boolean ppm, boolean ppt, boolean tempSop, boolean tempEph) { this.outname = outname; this.nt=nt; this.pptp = pptp; this.ppmUsed = ppm; this.pptUsed = ppt; this.tempSop = tempSop; this.tempEph = tempEph; } /** * This method performs the actual manipulation of the codestream which is * the reparsing for tile parts and packed packet headers * * @return The number of bytes that the file has increased by * * @exception java.io.IOException If an I/O error ocurred. * */ public int doCodestreamManipulation() throws IOException{ BEBufferedRandomAccessFile fi; int addedHeaderBytes=0; ppt = new int[nt]; tileParts = new byte[nt][][]; tileHeaders = new byte[nt][]; packetHeaders = new byte[nt][][]; packetData = new byte[nt][][]; sopMarkSeg = new byte[nt][][]; // If neither packed packet header nor tile parts are used, return 0 if( ppmUsed == false && pptUsed == false && pptp == 0) return 0; // Open file for reading and writing fi = new BEBufferedRandomAccessFile(outname,"rw+"); addedHeaderBytes -= fi.length(); // Parse the codestream for SOT, SOP and EPH markers parseAndFind(fi); // Read and buffer the tile headers, packet headers and packet data readAndBuffer(fi); // Close file and overwrite with new file fi.close(); fi = new BEBufferedRandomAccessFile(outname,"rw"); // Create tile-parts createTileParts(); // Write new codestream writeNewCodestream(fi); // Close file fi.flush(); addedHeaderBytes += fi.length(); fi.close(); return addedHeaderBytes; } /** * This method parses the codestream for SOT, SOP and EPH markers and * removes header header bits signalling SOP and EPH markers if packed * packet headers are used * * @param fi The file to parse the markers from * * @exception java.io.IOException If an I/O error ocurred. * */ private void parseAndFind(BufferedRandomAccessFile fi) throws IOException{ int length,pos,i,t,sop=0,eph=0; short marker; int halfMarker; int tileEnd; Vector markPos = new Vector(); // Find position of first SOT marker marker = (short)fi.readUnsignedShort(); // read SOC marker marker = (short)fi.readUnsignedShort(); while(marker != Markers.SOT){ pos = fi.getPos(); length = fi.readUnsignedShort(); // If SOP and EPH markers were only used for parsing in this // class remove SOP and EPH markers from Scod field if(marker == Markers.COD){ int scod = fi.readUnsignedByte(); if(tempSop) scod &= 0xfd; // Remove bits indicating SOP if(tempEph) scod &= 0xfb; // Remove bits indicating SOP fi.seek(pos +2); fi.write(scod); } fi.seek(pos + length); marker = (short)fi.readUnsignedShort(); } pos = fi.getPos(); fi.seek(pos-2); // Find all packet headers, packed data and tile headers for(t=0;t<nt;t++){ // Read SOT marker fi.readUnsignedShort(); // Skip SOT pos = fi.getPos(); markPos.addElement(new Integer(fi.getPos())); fi.readInt(); // Skip Lsot and Isot length = fi.readInt(); // Read Psot fi.readUnsignedShort(); // Skip TPsot & TNsot tileEnd = pos + length-2; // Last byte of tile // Find position of SOD marker marker = (short)fi.readUnsignedShort(); while(marker != Markers.SOD){ pos = fi.getPos(); length = fi.readUnsignedShort(); // If SOP and EPH markers were only used for parsing in this // class remove SOP and EPH markers from Scod field if(marker == Markers.COD){ int scod = fi.readUnsignedByte(); if(tempSop) scod &= 0xfd; // Remove bits indicating SOP if(tempEph) scod &= 0xfb; // Remove bits indicating SOP fi.seek(pos +2); fi.write(scod); } fi.seek(pos + length); marker = (short)fi.readUnsignedShort(); } // Find all SOP and EPH markers in tile sop = 0; eph = 0; i = fi.getPos(); while(i<tileEnd){ halfMarker = (short) fi.readUnsignedByte(); if(halfMarker == (short)0xff){ marker = (short)((halfMarker<<8) + fi.readUnsignedByte()); i++; if(marker == Markers.SOP){ markPos.addElement(new Integer(fi.getPos())); ppt[t]++; sop++; fi.skipBytes(4); i+=4; } if(marker == Markers.EPH){ markPos.addElement(new Integer(fi.getPos())); eph++; } } i++; } } markPos.addElement(new Integer(fi.getPos()+2)); positions = new Integer[markPos.size()]; markPos.copyInto(positions); } /** * This method reads and buffers the tile headers, packet headers and * packet data. * * @param fi The file to read the headers and data from * * @exception java.io.IOException If an I/O error ocurred. * */ private void readAndBuffer(BufferedRandomAccessFile fi)throws IOException{ int p,prem,length,t,markIndex; // Buffer main header fi.seek(0); length = ((Integer)positions[0]).intValue()-2; mainHeader = new byte[length]; fi.readFully(mainHeader,0,length); markIndex = 0; for(t=0; t<nt; t++){ prem = ppt[t]; packetHeaders[t] = new byte[prem][]; packetData[t] = new byte[prem][]; sopMarkSeg[t] = new byte[prem][]; // Read tile header length = positions[ markIndex+1 ].intValue() - positions[ markIndex ].intValue(); tileHeaders[t] = new byte[length]; fi.readFully(tileHeaders[t],0,length); markIndex++; for(p=0; p<prem; p++){ // Read packet header length = positions[ markIndex+1 ].intValue() - positions[ markIndex ].intValue(); if(tempSop){ // SOP marker is skipped length -= Markers.SOP_LENGTH; fi.skipBytes(Markers.SOP_LENGTH); } else{ // SOP marker is read and buffered length -= Markers.SOP_LENGTH; sopMarkSeg[t][p] = new byte[Markers.SOP_LENGTH]; fi.readFully(sopMarkSeg[t][p],0,Markers.SOP_LENGTH); } if(!tempEph){ // EPH marker is kept in header length += Markers.EPH_LENGTH; } packetHeaders[t][p] = new byte[length]; fi.readFully(packetHeaders[t][p],0,length); markIndex++; // Read packet data length = positions[ markIndex+1 ].intValue() - positions[ markIndex ].intValue();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?