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 + -
显示快捷键?