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

jj2000.j2k.codestream.writer.HeaderEncoder 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: HeaderEncoder.java,v $
 * $Revision: 1.1 $
 * $Date: 2005/02/11 05:02:02 $
 * $State: Exp $
 *
 * Class:                   HeaderEncoder
 *
 * Description:             Write codestream headers.
 *
 *
 *
 * 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.beans.Encoder;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.StringTokenizer;
import java.util.Vector;

import jj2000.j2k.JJ2KInfo;
import jj2000.j2k.ModuleSpec;
import jj2000.j2k.codestream.Markers;
import jj2000.j2k.entropy.Progression;
import jj2000.j2k.entropy.StdEntropyCoderOptions;
import jj2000.j2k.entropy.encoder.EBCOTRateAllocator;
import jj2000.j2k.entropy.encoder.PostCompRateAllocator;
import jj2000.j2k.image.ImgData;
import jj2000.j2k.image.Tiler;
import jj2000.j2k.io.BinaryDataOutput;
import jj2000.j2k.quantization.quantizer.StdQuantizer;
import jj2000.j2k.roi.encoder.ROIScaler;
import jj2000.j2k.util.MathUtil;
import jj2000.j2k.wavelet.analysis.AnWTFilter;
import jj2000.j2k.wavelet.analysis.ForwardWT;
import jj2000.j2k.wavelet.analysis.SubbandAn;

import com.github.jaiimageio.jpeg2000.impl.J2KImageWriteParamJava;
/**
 * This class writes almost of the markers and marker segments in main header
 * and in tile-part headers. It is created by the run() method of the Encoder
 * instance.
 *
 * 

A marker segment includes a marker and eventually marker segment * parameters. It is designed by the three letter code of the marker * associated with the marker segment. JPEG 2000 part I defines 6 types of * markers:

  • Delimiting : SOC,SOT,SOD,EOC (written in * FileCodestreamWriter).
  • Fixed information: SIZ.
  • * Functional: COD,COC,RGN,QCD,QCC,POC.
  • In bit-stream: SOP,EPH.
  • *
  • Pointer: TLM,PLM,PLT,PPM,PPT.
  • Informational: * CRG,COM.
* *

Main Header is written when Encoder instance calls encodeMainHeader * whereas tile-part headers are written when the EBCOTRateAllocator instance * calls encodeTilePartHeader. * * @see Encoder * @see Markers * @see EBCOTRateAllocator * */ public class HeaderEncoder implements Markers, StdEntropyCoderOptions { /** Nominal range bit of the component defining default values in QCD for * main header */ private int defimgn; /** Nominal range bit of the component defining default values in QCD for * tile headers */ private int deftilenr; /** The number of components in the image */ protected int nComp; /** Whether or not to write the JJ2000 COM marker segment */ private boolean enJJ2KMarkSeg = true; /** Other COM marker segments specified in the command line */ private String otherCOMMarkSeg = null; /** The ByteArrayOutputStream to store header data. This handler * is kept in order to use methods not accessible from a general * DataOutputStream. For the other methods, it's better to use * variable hbuf. * * @see #hbuf */ protected ByteArrayOutputStream baos; /** The DataOutputStream to store header data. This kind of object * is useful to write short, int, .... It's constructor takes * baos as parameter. * * @see #baos **/ protected DataOutputStream hbuf; /** The image data reader. Source of original data info */ protected ImgData origSrc; /** An array specifying, for each component,if the data was signed or not */ protected boolean isOrigSig[]; /** Reference to the rate allocator */ protected PostCompRateAllocator ralloc; /** Reference to the DWT module */ protected ForwardWT dwt; /** Reference to the tiler module */ protected Tiler tiler; /** Reference to the ROI module */ protected ROIScaler roiSc; /** The encoder specifications */ protected J2KImageWriteParamJava wp; /** * Initializes the header writer with the references to the coding chain. * * @param origsrc The original image data (before any component mixing, * tiling, etc.) * * @param isorigsig An array specifying for each component if it was * originally signed or not. * * @param dwt The discrete wavelet transform module. * * @param tiler The tiler module. * * @param encSpec The encoder specifications * * @param roiSc The ROI scaler module. * * @param ralloc The post compression rate allocator. * */ public HeaderEncoder(ImgData origsrc, boolean isorigsig[], ForwardWT dwt, Tiler tiler,J2KImageWriteParamJava wp, ROIScaler roiSc, PostCompRateAllocator ralloc) { if (origsrc.getNumComps() != isorigsig.length) { throw new IllegalArgumentException(); } this.origSrc = origsrc; this.isOrigSig = isorigsig; this.dwt = dwt; this.tiler = tiler; this.wp = wp; this.roiSc = roiSc; this.ralloc = ralloc; baos = new ByteArrayOutputStream(); hbuf = new DataOutputStream(baos); nComp = origsrc.getNumComps(); // enJJ2KMarkSeg = wp.getHjj2000_COM(); // otherCOMMarkSeg = wp.getHCOM(); } /** * Resets the contents of this HeaderEncoder to its initial state. It * erases all the data in the header buffer and reactualizes the * headerLength field of the bit stream writer. * */ public void reset() { baos.reset(); hbuf = new DataOutputStream(baos); } /** * Returns the byte-buffer used to store the codestream header. * * @return A byte array countaining codestream header * */ protected byte[] getBuffer(){ return baos.toByteArray(); } /** * Returns the length of the header. * * @return The length of the header in bytes * */ public int getLength() { return hbuf.size(); } /** * Writes the header to the specified BinaryDataOutput. * * @param out Where to write the header. * */ public void writeTo(BinaryDataOutput out) throws IOException { int i,len; byte buf[]; buf = getBuffer(); len = getLength(); for (i=0; iThe values can be overriden for an individual component by a COC * marker in either the main or the tile header. * * @param mh Flag indicating whether this marker belongs to the main * header * * @param tileIdx Tile index if the marker belongs to a tile-part header * * @see #writeCOC * */ protected void writeCOD(boolean mh, int tileIdx) throws IOException { AnWTFilter[][] filt; boolean precinctPartitionUsed; int tmp; int mrl=0,a=0; int ppx=0, ppy=0; Progression[] prog; if (mh) { mrl = ((Integer)wp.getDecompositionLevel().getDefault()).intValue(); // get default precinct size ppx = wp.getPrecinctPartition().getPPX(-1,-1,mrl); ppy = wp.getPrecinctPartition().getPPY(-1,-1,mrl); prog = (Progression[])(wp.getProgressionType().getDefault()); } else { mrl = ((Integer)wp.getDecompositionLevel().getTileDef(tileIdx)).intValue(); // get precinct size for specified tile ppx = wp.getPrecinctPartition().getPPX(tileIdx,-1,mrl); ppy = wp.getPrecinctPartition().getPPY(tileIdx,-1,mrl); prog = (Progression[])(wp.getProgressionType().getTileDef(tileIdx)); } if ( ppx != PRECINCT_PARTITION_DEF_SIZE || ppy != PRECINCT_PARTITION_DEF_SIZE ) { precinctPartitionUsed = true; } else { precinctPartitionUsed = false; } if ( precinctPartitionUsed ) { // If precinct partition is used we add one byte per resolution // level i.e. mrl+1 (+1 for resolution 0). a = mrl+1; } // Write COD marker hbuf.writeShort(COD); // Lcod (marker segment length (in bytes)) Basic : Lcod(2 // bytes)+Scod(1)+SGcod(4)+SPcod(5+a) where: // a=0 if no precinct partition is used // a=mrl+1 if precinct partition used int markSegLen = 12+a; hbuf.writeShort(markSegLen); // Scod (coding style parameter) tmp=0; if ( precinctPartitionUsed ) tmp=SCOX_PRECINCT_PARTITION; // Are SOP markers used ? if (mh) { if( ((String)wp.getSOP().getDefault().toString()) .equalsIgnoreCase("true") ) { tmp |= SCOX_USE_SOP; } } else { if ( ((String)wp.getSOP().getTileDef(tileIdx).toString()) .equalsIgnoreCase("true") ) { tmp |= SCOX_USE_SOP; } } // Are EPH markers used ? if(mh){ if ( ((String)wp.getEPH().getDefault().toString()) .equalsIgnoreCase("true") ) { tmp |= SCOX_USE_EPH; } } else{ if ( ((String)wp.getEPH().getTileDef(tileIdx).toString()) .equalsIgnoreCase("true") ) { tmp |= SCOX_USE_EPH; } } if (dwt.getCbULX()!=0) tmp |= SCOX_HOR_CB_PART; if (dwt.getCbULY()!=0) tmp |= SCOX_VER_CB_PART; hbuf.write(tmp); // SGcod // Progression order hbuf.write(prog[0].type); // Number of layers hbuf.writeShort(ralloc.getNumLayers()); // Multiple component transform // CSsiz (Color transform) String str = null; if(mh) str = (String)wp.getComponentTransformation().getDefault(); else str = (String)wp.getComponentTransformation().getTileDef(tileIdx); if(str.equals("none")) hbuf.write(0); else hbuf.write(1); // SPcod // Number of decomposition levels hbuf.write(mrl); // Code-block width and height if ( mh ) { // main header, get default values tmp = wp.getCodeBlockSize(). getCBlkWidth(ModuleSpec.SPEC_DEF,-1,-1); hbuf.write(MathUtil.log2(tmp)-2); tmp = wp.getCodeBlockSize(). getCBlkHeight(ModuleSpec.SPEC_DEF,-1,-1); hbuf.write(MathUtil.log2(tmp)-2); } else { // tile header, get tile default values tmp = wp.getCodeBlockSize(). getCBlkWidth(ModuleSpec.SPEC_TILE_DEF,tileIdx,-1); hbuf.write(MathUtil.log2(tmp)-2); tmp = wp.getCodeBlockSize(). getCBlkHeight(ModuleSpec.SPEC_TILE_DEF,tileIdx,-1); hbuf.write(MathUtil.log2(tmp)-2); } // Style of the code-block coding passes tmp = 0; if(mh){ // Main header // Selective arithmetic coding bypass ? if( ((String)wp.getBypass().getDefault()).equals("true")) { tmp |= OPT_BYPASS; } // MQ reset after each coding pass ? if( ((String)wp.getResetMQ().getDefault()).equals("true")) { tmp |= OPT_RESET_MQ; } // MQ termination after each arithmetically coded coding pass ? if( ((String)wp.getTerminateOnByte().getDefault()).equals("true") ) { tmp |= OPT_TERM_PASS; } // Vertically stripe-causal context mode ? if( ((String)wp.getCausalCXInfo().getDefault()).equals("true") ) { tmp |= OPT_VERT_STR_CAUSAL; } // Predictable termination ? if( ((String)wp.getMethodForMQTermination().getDefault()).equals("predict")){ tmp |= OPT_PRED_TERM; } // Error resilience segmentation symbol insertion ? if( ((String)wp.getCodeSegSymbol().getDefault()).equals("true")) { tmp |= OPT_SEG_SYMBOLS; } } else{ // Tile header // Selective arithmetic coding bypass ? if( ((String)wp.getBypass().getTileDef(tileIdx)).equals("true")) { tmp |= OPT_BYPASS; } // MQ reset after each coding pass ? if( ((String)wp.getResetMQ().getTileDef(tileIdx)).equals("true")) { tmp |= OPT_RESET_MQ; } // MQ termination after each arithmetically coded coding pass ? if( ((String)wp.getTerminateOnByte().getTileDef(tileIdx)).equals("true") ) { tmp |= OPT_TERM_PASS; } // Vertically stripe-causal context mode ? if( ((String)wp.getCausalCXInfo().getTileDef(tileIdx)).equals("true") ) { tmp |= OPT_VERT_STR_CAUSAL; } // Predictable termination ? if( ((String)wp.getMethodForMQTermination().getTileDef(tileIdx)).equals("predict")){ tmp |= OPT_PRED_TERM; } // Error resilience segmentation symbol insertion ? if( ((String)wp.getCodeSegSymbol().getTileDef(tileIdx)).equals("true")) { tmp |= OPT_SEG_SYMBOLS; } } hbuf.write(tmp); // Wavelet transform // Wavelet Filter if(mh){ filt=((AnWTFilter[][])wp.getFilters().getDefault()); hbuf.write(filt[0][0].getFilterType()); }else{ filt=((AnWTFilter[][])wp.getFilters().getTileDef(tileIdx)); hbuf.write(filt[0][0].getFilterType()); } // Precinct partition if ( precinctPartitionUsed ) { // Write the precinct size for each resolution level + 1 // (resolution 0) if precinct partition is used. Vector v[] = null; if ( mh ) { v = (Vector[])wp.getPrecinctPartition().getDefault(); } else { v = (Vector[])wp.getPrecinctPartition().getTileDef(tileIdx); } for (int r=mrl ; r>=0 ; r--) { if ( r>=v[1].size() ) { tmp = ((Integer)v[1].elementAt(v[1].size()-1)). intValue(); } else { tmp = ((Integer)v[1].elementAt(r)).intValue(); } int yExp = (MathUtil.log2(tmp)<< 4) & 0x00F0; if ( r>=v[0].size() ) { tmp = ((Integer)v[0].elementAt(v[0].size()-1)). intValue(); } else { tmp = ((Integer)v[0].elementAt(r)).intValue(); } int xExp = MathUtil.log2(tmp) & 0x000F; hbuf.write(yExp|xExp); } } } /** * Writes COC marker segment . It is a functional marker containing the * coding style for one component (coding style, decomposition, layering). * *

Its values overrides any value previously set in COD in the main * header or in the tile header. * * @param mh Flag indicating whether the main header is to be written * * @param tileIdx Tile index * * @param compIdx index of the component which need use of the COC marker * segment. * * @see #writeCOD * */ protected void writeCOC(boolean mh, int tileIdx, int compIdx) throws IOException { AnWTFilter[][] filt; boolean precinctPartitionUsed; int tmp; int mrl=0,a=0; int ppx=0, ppy=0; Progression[] prog; if (mh) { mrl = ((Integer)wp.getDecompositionLevel().getCompDef(compIdx)).intValue(); // Get precinct size for specified component ppx = wp.getPrecinctPartition().getPPX(-1, compIdx, mrl); ppy = wp.getPrecinctPartition().getPPY(-1, compIdx, mrl); prog = (Progression[])(wp.getProgressionType().getCompDef(compIdx)); } else { mrl = ((Integer)wp.getDecompositionLevel().getTileCompVal(tileIdx,compIdx)). intValue(); // Get precinct size for specified component/tile ppx = wp.getPrecinctPartition().getPPX(tileIdx, compIdx, mrl); ppy = wp.getPrecinctPartition().getPPY(tileIdx, compIdx, mrl); prog = (Progression[])(wp.getProgressionType().getTileCompVal(tileIdx,compIdx)); } if ( ppx != Markers.PRECINCT_PARTITION_DEF_SIZE || ppy != Markers.PRECINCT_PARTITION_DEF_SIZE ) { precinctPartitionUsed = true; } else { precinctPartitionUsed = false; } if ( precinctPartitionUsed ) { // If precinct partition is used we add one byte per resolution // level i.e. mrl+1 (+1 for resolution 0). a = mrl+1; } // COC marker hbuf.writeShort(COC); // Lcoc (marker segment length (in bytes)) // Basic: Lcoc(2 bytes)+Scoc(1)+ Ccoc(1 or 2)+SPcod(5+a) int markSegLen = 8 + ((nComp < 257) ? 1 : 2)+a; // Rounded to the nearest even value greater or equals hbuf.writeShort(markSegLen); // Ccoc if(nComp < 257) { hbuf.write(compIdx); } else { hbuf.writeShort(compIdx); } // Scod (coding style parameter) tmp=0; if ( precinctPartitionUsed ) { tmp=SCOX_PRECINCT_PARTITION; } hbuf.write(tmp); // SPcoc // Number of decomposition levels hbuf.write(mrl); // Code-block width and height if ( mh ) { // main header, get component default values tmp = wp.getCodeBlockSize(). getCBlkWidth(ModuleSpec.SPEC_COMP_DEF, -1, compIdx); hbuf.write(MathUtil.log2(tmp)-2); tmp = wp.getCodeBlockSize(). getCBlkHeight(ModuleSpec.SPEC_COMP_DEF, -1, compIdx); hbuf.write(MathUtil.log2(tmp)-2); } else { // tile header, get tile component values tmp = wp.getCodeBlockSize(). getCBlkWidth(ModuleSpec.SPEC_TILE_COMP, tileIdx, compIdx); hbuf.write(MathUtil.log2(tmp)-2); tmp = wp.getCodeBlockSize(). getCBlkHeight(ModuleSpec.SPEC_TILE_COMP, tileIdx, compIdx); hbuf.write(MathUtil.log2(tmp)-2); } // Entropy coding mode options tmp = 0; if(mh){ // Main header // Lazy coding mode ? if( ((String)wp.getBypass().getCompDef(compIdx)).equals("true")) { tmp |= OPT_BYPASS; } // MQ reset after each coding pass ? if( ((String)wp.getResetMQ().getCompDef(compIdx)). equalsIgnoreCase("true")) { tmp |= OPT_RESET_MQ; } // MQ termination after each arithmetically coded coding pass ? if( ((String)wp.getTerminateOnByte().getCompDef(compIdx)).equals("true") ) { tmp |= OPT_TERM_PASS; } // Vertically stripe-causal context mode ? if( ((String)wp.getCausalCXInfo().getCompDef(compIdx)).equals("true") ) { tmp |= OPT_VERT_STR_CAUSAL; } // Predictable termination ? if( ((String)wp.getMethodForMQTermination().getCompDef(compIdx)).equals("predict")){ tmp |= OPT_PRED_TERM; } // Error resilience segmentation symbol insertion ? if( ((String)wp.getCodeSegSymbol().getCompDef(compIdx)).equals("true")) { tmp |= OPT_SEG_SYMBOLS; } } else{ // Tile Header if( ((String)wp.getBypass().getTileCompVal(tileIdx,compIdx)). equals("true")) { tmp |= OPT_BYPASS; } // MQ reset after each coding pass ? if( ((String)wp.getResetMQ().getTileCompVal(tileIdx,compIdx)). equals("true")) { tmp |= OPT_RESET_MQ; } // MQ termination after each arithmetically coded coding pass ? if( ((String)wp.getTerminateOnByte().getTileCompVal(tileIdx,compIdx)). equals("true") ) { tmp |= OPT_TERM_PASS; } // Vertically stripe-causal context mode ? if( ((String)wp.getCausalCXInfo().getTileCompVal(tileIdx,compIdx)). equals("true") ) { tmp |= OPT_VERT_STR_CAUSAL; } // Predictable termination ? if( ((String)wp.getMethodForMQTermination().getTileCompVal(tileIdx,compIdx)). equals("predict")){ tmp |= OPT_PRED_TERM; } // Error resilience segmentation symbol insertion ? if( ((String)wp.getCodeSegSymbol().getTileCompVal(tileIdx,compIdx)). equals("true")) { tmp |= OPT_SEG_SYMBOLS; } } hbuf.write(tmp); // Wavelet transform // Wavelet Filter if(mh){ filt=((AnWTFilter[][])wp.getFilters().getCompDef(compIdx)); hbuf.write(filt[0][0].getFilterType()); }else{ filt=((AnWTFilter[][])wp.getFilters().getTileCompVal(tileIdx,compIdx)); hbuf.write(filt[0][0].getFilterType()); } // Precinct partition if ( precinctPartitionUsed ) { // Write the precinct size for each resolution level + 1 // (resolution 0) if precinct partition is used. Vector v[] = null; if ( mh ) { v = (Vector[])wp.getPrecinctPartition().getCompDef(compIdx); } else { v = (Vector[])wp.getPrecinctPartition().getTileCompVal(tileIdx, compIdx); } for (int r=mrl ; r>=0 ; r--) { if ( r>=v[1].size() ) { tmp = ((Integer)v[1].elementAt(v[1].size()-1)). intValue(); } else { tmp = ((Integer)v[1].elementAt(r)).intValue(); } int yExp = (MathUtil.log2(tmp)<< 4) & 0x00F0; if ( r>=v[0].size() ) { tmp = ((Integer)v[0].elementAt(v[0].size()-1)). intValue(); } else { tmp = ((Integer)v[0].elementAt(r)).intValue(); } int xExp = MathUtil.log2(tmp) & 0x000F; hbuf.write(yExp|xExp); } } } /** * Writes QCD marker segment in main header. QCD is a functional marker * segment countaining the quantization default used for compressing all * the components in an image. The values can be overriden for an * individual component by a QCC marker in either the main or the tile * header. * */ protected void writeMainQCD() throws IOException{ float step; String qType = (String)wp.getQuantizationType().getDefault(); float baseStep = ((Float)wp.getQuantizationStep().getDefault()).floatValue(); int gb = ((Integer)wp.getGuardBits().getDefault()).intValue(); boolean isDerived = qType.equals("derived"); boolean isReversible = qType.equals("reversible"); int mrl = ((Integer)wp.getDecompositionLevel().getDefault()).intValue(); int nt = dwt.getNumTiles(); int nc = dwt.getNumComps(); int tmpI; int[] tcIdx = new int[2]; String tmpStr; boolean notFound = true; for(int t=0; t

  • SOC
  • SIZ
  • COD
  • COC (if * needed)
  • QCD
  • QCC (if needed)
  • POC (if * needed)
  • * */ public void encodeMainHeader() throws IOException { int i; // +---------------------------------+ // | SOC marker segment | // +---------------------------------+ writeSOC(); // +---------------------------------+ // | Image and tile SIZe (SIZ) | // +---------------------------------+ writeSIZ(); // +-------------------------------+ // | COding style Default (COD) | // +-------------------------------+ boolean isEresUsed = ((String)wp.getTerminateOnByte().getDefault()). equals("predict"); writeCOD(true,0); // +---------------------------------+ // | COding style Component (COC) | // +---------------------------------+ for (i= 0; i need COC writeCOC(true,0,i); } // +-------------------------------+ // | Quantization Default (QCD) | // +-------------------------------+ writeMainQCD(); // +-------------------------------+ // | Quantization Component (QCC) | // +-------------------------------+ // Write needed QCC markers for(i=0; i1) writePOC(true, 0); // +--------------------------+ // | Comment (COM) | // +--------------------------+ writeCOM(); } /** * Write a COM marker segment adding some comments to the codestream. * *

    This marker is currently written in main header and indicates the * JJ2000 encoder's version that has created the codestream. * */ private void writeCOM() throws IOException { // JJ2000 COM marker segment if(enJJ2KMarkSeg) { String str = "Created by: JJ2000 version "+JJ2KInfo.version; int markSegLen; // the marker segment length // COM marker hbuf.writeShort(COM); // Calculate length: Lcom(2) + Rcom (2) + string's length; markSegLen = 2 + 2 + str.length(); hbuf.writeShort(markSegLen); // Rcom hbuf.writeShort(1); // General use (IS 8859-15:1999(Latin) values) byte[] chars = str.getBytes(); for(int i=0; iMay be used in tile or main header. If used in main header, it * refers to a ROI of the whole image, regardless of tiling. When used in * tile header, only the particular tile is affected. * * @param tIdx The tile index * * @exception IOException If an I/O error occurs while reading from the * encoder header stream * */ private void writeRGN(int tIdx) throws IOException { int i; int markSegLen; // the marker length // Write one RGN marker per component for(i=0;i

  • SOT
  • COD (if * needed)
  • COC (if needed)
  • QCD (if needed)
  • QCC * (if needed)
  • RGN (if needed)
  • POC (if needed)
  • *
  • SOD
  • * * @param length The length of the current tile-part. * * @param tileIdx Index of the tile to write * */ public void encodeTilePartHeader(int tileLength,int tileIdx) throws IOException { int tmp; Point numTiles = ralloc.getNumTiles(null); ralloc.setTile(tileIdx%numTiles.x,tileIdx/numTiles.x); // +--------------------------+ // | SOT maker segment | // +--------------------------+ // SOT marker hbuf.writeByte(SOT>>8); hbuf.writeByte(SOT); // Lsot (10 bytes) hbuf.writeByte(0); hbuf.writeByte(10); // Isot if(tileIdx>65534){ throw new IllegalArgumentException("Trying to write a tile-part "+ "header whose tile index is too"+ " high"); } hbuf.writeByte(tileIdx>>8); hbuf.writeByte(tileIdx); // Psot tmp = tileLength; hbuf.writeByte(tmp>>24); hbuf.writeByte(tmp>>16); hbuf.writeByte(tmp>>8); hbuf.writeByte(tmp); // TPsot hbuf.writeByte(0); // Only one tile-part currently supported ! // TNsot hbuf.writeByte(1); // Only one tile-part currently supported ! // +--------------------------+ // | COD maker segment | // +--------------------------+ boolean isEresUsed = ((String)wp.getMethodForMQTermination().getDefault()). equals("predict"); boolean isEresUsedInTile = ((String)wp.getMethodForMQTermination().getTileDef(tileIdx)). equals("predict"); boolean tileCODwritten = false; if(wp.getFilters().isTileSpecified(tileIdx) || wp.getComponentTransformation().isTileSpecified(tileIdx) || wp.getDecompositionLevel().isTileSpecified(tileIdx) || wp.getBypass().isTileSpecified(tileIdx) || wp.getResetMQ().isTileSpecified(tileIdx) || wp.getTerminateOnByte().isTileSpecified(tileIdx) || wp.getCausalCXInfo().isTileSpecified(tileIdx) || wp.getPrecinctPartition().isTileSpecified(tileIdx) || wp.getSOP().isTileSpecified(tileIdx) || wp.getCodeSegSymbol().isTileSpecified(tileIdx) || wp.getProgressionType().isTileSpecified(tileIdx) || wp.getEPH().isTileSpecified(tileIdx) || wp.getCodeBlockSize().isTileSpecified(tileIdx) || ( isEresUsed != isEresUsedInTile ) ) { writeCOD(false,tileIdx); tileCODwritten = true; } // +--------------------------+ // | COC maker segment | // +--------------------------+ for(int c=0; c1) writePOC(false,tileIdx); } // +--------------------------+ // | SOD maker | // +--------------------------+ hbuf.writeByte(SOD>>8); hbuf.writeByte(SOD); } }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy