com.github.jaiimageio.jpeg2000.impl.J2KImageWriteParamJava Maven / Gradle / Ivy
Show all versions of jai-imageio-jpeg2000 Show documentation
/*
* $RCSfile: J2KImageWriteParamJava.java,v $
*
*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
* NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
* USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
* ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
* CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
* REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
* INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for
* use in the design, construction, operation or maintenance of any
* nuclear facility.
*
* $Revision: 1.2 $
* $Date: 2006/09/20 23:23:30 $
* $State: Exp $
*/
package com.github.jaiimageio.jpeg2000.impl;
import java.awt.Rectangle;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.util.Locale;
import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import jj2000.j2k.IntegerSpec;
import jj2000.j2k.ModuleSpec;
import jj2000.j2k.StringSpec;
import jj2000.j2k.entropy.CBlkSizeSpec;
import jj2000.j2k.entropy.PrecinctSizeSpec;
import jj2000.j2k.entropy.ProgressionSpec;
import jj2000.j2k.entropy.encoder.LayersInfo;
import jj2000.j2k.image.forwcomptransf.ForwCompTransfSpec;
import jj2000.j2k.quantization.GuardBitsSpec;
import jj2000.j2k.quantization.QuantStepSizeSpec;
import jj2000.j2k.quantization.QuantTypeSpec;
import jj2000.j2k.roi.MaxShiftSpec;
import jj2000.j2k.wavelet.analysis.AnWTFilterSpec;
import com.github.jaiimageio.jpeg2000.J2KImageWriteParam;
/**
* A subclass of ImageWriteParam
for writing images in
* the JPEG 2000 format.
*
* JPEG 2000 plugin supports to losslessly or lossy compress gray-scale,
* RGB, and RGBA images with byte, unsigned short or short data type. It also
* supports losslessly compress bilevel, and 8-bit indexed. The result data
* is in the format of JP2 (JPEG 2000 Part 1 or baseline format).
*
*
Many encoding parameters for JPEG 2000 can be tile-component specific.
* These parameters are marked as Yes
in the column
* TC_SPEC
in the following parameter table.
* They must be provided according to the pattern:
* [<tile-component idx>] <param> (repeated as many time as needed),
* where <tile-component idx> respect the following policy according to
* the degree of priority:
*
* (1) t<idx> c<idx> : Tile-component specification.
* (2) t<idx> : Tile specification.
* (3) c<idx> : Component specification.
* (4) <void> : Default specification.
*
* Where the priorities of the specifications are:
* (1) > (2) > (3) > (4), (">" means "overrides")
* <idx>: "," separates indexes, "-" separates bounds of indexes list.
* (for example, 0,2-4 means indexes 0,2,3 and 4).
*
*
The parameters for encoding JPEG 2000 are listed in the following table:
*
* *
* JPEG 2000 Plugin Decoding Parameters
* Parameter Name Description TC_SPEC
*
* encodingRate
* The bitrate in bits-per-pixel for encoding. Should be set when
* lossy compression scheme is used. With the default value
* Double.MAX_VALUE
, a lossless compression will be done.
*
* No
*
*
* lossless
* Indicates using the loseless scheme or not. It is equivalent to
* use reversible quantization and 5x3 integer wavelet filters. The
* default is true
.
*
* No
*
*
* componentTransformation
* Specifies to utilize the component transformation on some tiles.
* If the wavelet transform is reversible (w5x3 filter), the Reversible
* Component Transformation (RCT) is applied. If not reversible
* (w9x7 filter), the Irreversible Component Transformation (ICT) is used.
*
* Yes, Tile_Specific
*
*
* filters
* Specifies which wavelet filters to use for the specified
* tile-components. JPEG 2000 part I only supports w5x3 and w9x7 filters.
*
* Yes
*
*
* decompositionLevel
* Specifies the wavelet decomposition levels to apply to
* the image. If it is 0, no wavelet transform is performed, in which
* case the original image data will be sent to the encoder and an example
* is the binary data. All components and all tiles have the same number
* of decomposition levels. The default value is 5.
*
* No
*
*
* guardBits
* The number of bits used for each tile-component in the quantizer
* to avoid overflow. It takes values in the range 0 through 7. The
* default value is 2.
*
* Yes
*
*
* quantizationStep
* This parameter specifies the base normalized quantization step
* size for the tiles/components. It is normalized to a dynamic range
* of 1 in the image domain. This parameter is ignored in reversible
* coding. The default value is 0.0078125.
*
* Yes
*
*
* quantizationType
* Specifies which quantization type to use for specified
* tiles/components. Not specified for lossless compression. By default,
* the quantization step size is "expounded". Supported quantization
* types specification are : "reversible" (no quantization), "derived"
* (derived quantization step size) and "expounded".
*
* Yes
*
*
* codeBlockSize
* Specifies the maximum code-block size to use for tile-component.
* The maximum width and height is 1024, however the block size
* (i.e. width x height) must not exceed 4096. The minimum width and
* height is 4. The default values are (64, 64).
*
* Yes
*
*
* progressionType
* Specifies which type of progression should be used when generating
* the codestream.
* The format is [<tile index>]
* res|layer|res-pos|pos-comp|comp-pos [res_start comp_start layer_end
* res_end comp_end prog] [[res_start comp_start layer_end res_end
* comp_end prog]...] [[<tile-component idx]...].
*
The value "res" generates a resolution progressive
* codestream with the number of layers specified by "layers" parameter.
* The value "layer" generates a layer progressive codestream with
* multiple layers. In any case, the rate-allocation algorithm optimizes
* for best quality in each layer. The quality measure is mean squared
* error (MSE) or a weighted version of it (WMSE). If no progression
* type is specified or imposed by other parameters, the default value
* is "layer". It is also possible to describe progression order
* changes. In this case, "res_start" is the index (from 0) of the
* first resolution level, "comp_start" is the index (from 0) of the
* first component, "layer_end" is the index (from 0) of the first layer
* not included, "res_end" is the index (from 0) of the first
* resolution level not included, "comp_end" is index (from 0) of
* the first component not included and "prog" is the progression type
* to be used for the rest of the tile/image. Several progression
* order changes can be specified, one after the other.
*
* Yes
*
*
* packPacketHeaderInTile
* Indicates that the packet headers are packed in the tiles' headers.
* The default is false.
*
* No
*
*
* packPacketHeaderInMain
* Indicates that the packet headers are packed in the main header.
* The default is false.
*
* No
*
*
* packetPerTilePart
* Specifies the maximum number of packets to be put into one tile-part.
* Zero means putting all packets in the first tile-part of each tile.
*
* No
*
*
* ROIs
* Specifies ROIs shape and location. The component index specifies
* which components contain the ROI. If this parameter is used, the
* codestream is layer progressive by default unless it is overridden by
* the progressionType
. A rectanglar or circular ROI can be
* specified in the format: [<component idx>] R <left>
* <top> <width> <height> or [<component idx>] C
* <center x> <center y> <radius>. An arbitrary shape
* can be assigned by [<component idx>] A <PGM file>
*
* Yes, component-specified
*
*
* startLevelROI
* This parameter defines the lowest resolution levels to belong to
* the ROI. By doing this, it is possible to avoid getting
* information for the ROI at an early stage of transmission.
* startLevelROI = 0 means the lowest resolution level belongs to
* the ROI, 1 means the second lowest etc. The default values, -1,
* deactivates this parameter.
*
* No
*
*
* alignROI
* By specifying this parameter, the ROI mask will be limited to
* covering only entire code-blocks. The ROI coding can then be
* performed without any actual scaling of the coefficients but by
* instead scaling the distortion estimates.
*
* No
*
*
* bypass
* Uses the lazy coding mode with the entropy coder. This will bypass
* the MQ coder for some of the coding passes, where the distribution
* is often close to uniform. Since the MQ codeword will be terminated
* at least once per lazy pass, it is important to use an efficient
* termination algorithm, methodForMQTermination
.
* true enables, and false disables it. The default value is false.
*
* Yes
*
*
* resetMQ
* If this is enabled the probability estimates of the MQ coder are
* reset after each arithmetically coded (i.e. non-lazy) coding pass.
* true enables, and false disables it. The default value is false.
*
* Yes
*
*
* terminateOnByte
* If this is enabled the codeword (raw or MQ) is terminated on a byte
* boundary after each coding pass. In this case it is important to use
* an efficient termination algorithm, "methodForMQTermination".
* true enables, and false disables it. The default value is false.
*
* Yes
*
*
* causalCXInfo
* Uses vertically stripe causal context formation. If this is
* enabled the context formation process in one stripe is independant of
* the next stripe (i.e. the one below it). true enables, and false
* disables it. The default value is false.
*
* Yes
*
*
* codeSegSymbol
* Inserts an error resilience segmentation symbol in the MQ codeword
* at the end of each bit-plane (cleanup pass). Decoders can use this
* information to detect and conceal errors. true enables, and false
* disables it. The default value is false.
*
* Yes
*
*
* methodForMQTermination
* Specifies the algorithm used to terminate the MQ codeword. The
* most efficient one is "near_opt", which delivers a codeword which
* in almost all cases is the shortest possible. The "easy" is a
* simpler algorithm that delivers a codeword length that is close
* to the previous one (in average 1 bit longer). The "predict" is
* almost the same as the "easy" but it leaves error resilient
* information on the spare least significant bits (in average 3.5 bits),
* which can be used by a decoder to detect errors. The "full" algorithm
* performs a full flush of the MQ coder and is highly inefficient. It
* is important to use a good termination policy since the MQ codeword
* can be terminated quite often, specially if the "bypass" or
* "terminateOnByte" parameters are enabled (in the normal case it would
* be terminated once per code-block, while "terminateOnByte" is specified
* it will be done almost 3 times per bit-plane in each code-block).
* The default value is "near_opt".
*
* Yes
*
*
* methodForMQLengthCalc
* Specifies the algorithm to use in calculating the necessary MQ
* length for each decoding pass. The best one is "near_opt", which
* performs a rather sophisticated calculation and provides the best
* results. The "lazy_good" and "lazy" are very simple algorithms
* that provide rather conservative results. "lazy_good" performs
* slightly better. Please use the default unless the experiments
* show the benefits of different length calculation algorithms.
* The default value is "near_opt".
*
* Yes
*
*
* precinctPartition
* Specifies precinct partition dimensions for tiles/components. They
* are stored from those applied to the highest resolution to those
* applied to the remaining resolutions in decreasing order. If less
* values than the number of decomposition levels are specified, then
* the last two values are used for the remaining resolutions.
*
* Yes
*
*
* layers
* Explicitly specifies the codestream layer formation parameters.
* The rate (double) parameter specifies the bitrate to which the first
* layer should be optimized. The layers (int) parameter, if present,
* specifies the number of extra layers that should be added for
* scalability. These extra layers are not optimized. Any extra rate
* and layers parameters add more layers, in the same way. An
* additional layer is always added at the end, which is optimized
* to the overall target bitrate of the bit stream. Any layers
* (optimized or not) whose target bitrate is higher that the overall
* target bitrate are silently ignored. The bitrates of the extra layers
* that are added through the layers parameter are approximately
* log-spaced between the other target bitrates. If several (rate, layers)
* constructs appear the rate parameters must appear in increasing order.
* The rate allocation algorithm ensures that all coded layers have a
* minimal reasonable size, if not these layers are silently ignored.
* Default: 0.015 +20 2.0 +10.
*
* No
*
*
* SOP
* Specifies whether start of packet (SOP) markers should be used.
* true enables, false disables it. The default value is false.
*
* Yes
*
*
* EPH
* Specifies whether end of packet header (EPH) markers should be used.
* true enables, false disables it. The default value is false.
*
* Yes
*
*
*/
public class J2KImageWriteParamJava extends ImageWriteParam {
/**
* Indicates that the packet headers are packed in the tiles' headers.
*/
private boolean packPacketHeaderInTile = false;
/**
* Indicates that the packet headers are packed in the main header.
*/
private boolean packPacketHeaderInMain = false;
/**
* Specifies the maximum number of packets to be put into one tile-part.
* Zero means include all packets in first tile-part of each tile.
*/
private int packetPerTilePart = 0;
/**
* The bitrate in bits-per-pixel for encoding. Should be set when lossy
* compression scheme is used. The default is
* Double.MAX_VALUE
.
*/
private double encodingRate = Double.MAX_VALUE;
/**
* Indicates using the loseless scheme or not. It is equivalent to
* use reversible quantization and 5x3 integer wavelet filters.
*/
private boolean lossless = true;
/** Specifies to utilize the component transformation with some tiles.
* If the wavelet transform is reversible (w5x3 filter), the
* Reversible Component Transformation (RCT) is applied. If not reversible
* (w9x7 filter), the Irreversible Component Transformation (ICT)
* is used.
*/
private ForwCompTransfSpec componentTransformation = null;
private boolean enableCT = true;
/** Specifies which filters to use for the specified tile-components.
* JPEG 2000 part I only supports w5x3 and w9x7 filters.
*/
private AnWTFilterSpec filters = null;
/** Specifies the number of wavelet decomposition levels to apply to
* the image. If it is 0, no wavelet transform is performed, in which
* case the original image data will be sent to the encoder and an
* example is the binary data. All components and all tiles have
* the same number of decomposition levels. Default: 5.
*/
private IntegerSpec decompositionLevel = null; // = 5;
/** The number of bits used for each tile-component in
* the quantizer to avoid overflow. It takes values in the range 0
* through 7. Default: 2.
*/
private GuardBitsSpec guardBits = null;
/** This parameter specifies the base normalized quantization step
* size for the tiles/components. It is normalized to a dynamic range
* of 1 in the image domain. This parameter is ignored in reversible
* coding. Default: 0.0078125.
*/
private QuantStepSizeSpec quantizationStep = null;
/** Specifies which quantization type to use for specified
* tiles/components. Not specified for lossless compression. By
* default , the quantization step size is "expounded". Supported
* quantization types specification are : "reversible" (no quantization),
* "derived" (derived quantization step size) and "expounded".
*/
private QuantTypeSpec quantizationType = null;
/** This parameter defines the lowest resolution levels to belong to
* the ROI. By doing this, it is possible to avoid only getting
* information for the ROI at an early stage of transmission.
* startLevelROI = 0 means the lowest resolution level belongs to
* the ROI, 1 means the second lowest etc. The default values, -1,
* deactivates this parameter.
*/
private int startLevelROI = -1;
/** By specifying this parameter, the ROI mask will be limited to
* covering only entire code-blocks. The ROI coding can then be
* performed without any actual scaling of the coefficients but
* by instead scaling the distortion estimates.
*/
private boolean alignROI = false;
/** Specifies ROIs shape and location. The component index specifies
* which components contain the ROI. If this parameter is used, the
* codestream is layer progressive by default unless it is
* overridden by the progressionType
.
*/
private MaxShiftSpec ROIs = null;
/** Specifies the maximum code-block size to use for tile-component.
* The maximum width and height is 1024, however the image area
* (i.e. width x height) must not exceed 4096. The minimum
* width and height is 4. Default: 64 64.
*/
private CBlkSizeSpec codeBlockSize = null;
/** Uses the lazy coding mode with the entropy coder. This will bypass
* the MQ coder for some of the coding passes, where the distribution
* is often close to uniform. Since the MQ codeword will be terminated
* at least once per lazy pass, it is important to use an efficient
* termination algorithm, methodForMQTermination
.
* true enables, and false disables it. Default: false.
*/
private StringSpec bypass = null;
/** If this is enabled the probability estimates of the MQ coder are
* reset after each arithmetically coded (i.e. non-lazy) coding pass.
* true enables, and false disables it. Default: false.
*/
private StringSpec resetMQ = null;
/** If this is enabled the codeword (raw or MQ) is terminated on a byte
* boundary after each coding pass. In this case it is important to
* use an efficient termination algorithm, the "methodForMQTermination".
* true enables, and false disables it. Default: false.
*/
private StringSpec terminateOnByte = null;
/** Uses vertically stripe causal context formation. If this is
* enabled the context formation process in one stripe is independant
* of the next stripe (i.e. the one below it). true enables, and
* false disables it. Default: false.
*/
private StringSpec causalCXInfo = null;
/** Inserts an error resilience segmentation symbol in the MQ codeword
* at the end of each bit-plane (cleanup pass). Decoders can use this
* information to detect and conceal errors. true enables,
* and false disables it. Default: false.
*/
private StringSpec codeSegSymbol = null;
/** Specifies the algorithm used to terminate the MQ codeword. The
* most efficient one is "near_opt", which delivers a codeword which
* in almost all cases is the shortest possible. The "easy" is a
* simpler algorithm that delivers a codeword length that is close
* to the previous one (in average 1 bit longer). The "predict" is
* almost the same as the "easy" but it leaves error resilient
* information on the spare least significant bits (in average
* 3.5 bits), which can be used by a decoder to detect errors.
* The "full" algorithm performs a full flush of the MQ coder and
* is highly inefficient. It is important to use a good termination
* policy since the MQ codeword can be terminated quite often,
* specially if the "bypass" or "terminateOnByte" parameters are
* enabled (in the normal case it would be terminated once per
* code-block, while "terminateOnByte" is specified it will be
* done almost 3 times per bit-plane in each code-block).
* Default: near_opt.
*/
private StringSpec methodForMQTermination = null;
/** Specifies the algorithm to use in calculating the necessary MQ
* length for each decoding pass. The best one is "near_opt", which
* performs a rather sophisticated calculation and provides the best
* results. The "lazy_good" and "lazy" are very simple algorithms
* that provide rather conservative results. "lazy_good" performs
* slightly better. Please use the default unless the experiments
* show the benefits of different length calculation algorithms.
* Default: near_opt.
*/
private StringSpec methodForMQLengthCalc = null;
/** Specifies precinct partition dimensions for tiles/components. They
* are stored from those applied to the highest resolution to those
* applied to the remaining resolutions in decreasing order. If less
* values than the number of decomposition levels are specified, then
* the last two values are used for the remaining resolutions.
*/
private PrecinctSizeSpec precinctPartition = null;
/** Specifies which type of progression should be used when generating
* the codestream. The value "res" generates a resolution progressive
* codestream with the number of layers specified by "layers" parameter.
* The value "layer" generates a layer progressive codestream with
* multiple layers. In any case, the rate-allocation algorithm optimizes
* for best quality in each layer. The quality measure is mean squared
* error (MSE) or a weighted version of it (WMSE). If no progression
* type is specified or imposed by other modules, the default value
* is "layer". It is also possible to describe progression order
* changes. In this case, "res_start" is the index (from 0) of the
* first resolution level, "comp_start" is the index (from 0) of the
* first component, "ly_end" is the index (from 0) of the first layer
* not included, "res_end" is the index (from 0) of the first
* resolution level not included, "comp_end" is index (from 0) of
* the first component not included and "prog" is the progression type
* to be used for the rest of the tile/image. Several progression
* order changes can be specified, one after the other.
*/
private ProgressionSpec progressionType = null;
/**
* The specified (tile-component) progression. Will be used to generate
* the progression type.
*/
private String progressionName = null;
/** Explicitly specifies the codestream layer formation parameters.
* The rate (double) parameter specifies the bitrate to which the first
* layer should be optimized. The layers (int) parameter, if present,
* specifies the number of extra layers that should be added for
* scalability. These extra layers are not optimized. Any extra rate
* and layers parameters add more layers, in the same way. An
* additional layer is always added at the end, which is optimized
* to the overall target bitrate of the bit stream. Any layers
* (optimized or not) whose target bitrate is higher that the
* overall target bitrate are silently ignored. The bitrates of
* the extra layers that are added through the layers parameter
* are approximately log-spaced between the other target bitrates.
* If several (rate, layers) constructs appear the rate parameters
* must appear in increasing order. The rate allocation algorithm
* ensures that all coded layers have a minimal reasonable size,
* if not these layers are silently ignored. Default: 0.015 +20 2.0 +10.
*/
private String layers = "0.015 +20 2.0 +10";
/** Specifies whether end of packet header (EPH) markers should be used.
* true enables, false disables it. Default: false.
*/
private StringSpec EPH = null;
/** Specifies whether start of packet (SOP) markers should be used.
* true enables, false disables it. Default: false.
*/
private StringSpec SOP = null;
private int numTiles;
private int numComponents;
private RenderedImage imgsrc;
private Raster raster;
private int minX;
private int minY;
/** Constructor to set locales. */
public J2KImageWriteParamJava(RenderedImage imgsrc, Locale locale) {
super(locale);
setDefaults(imgsrc);
}
/** Constructor to set locales. */
public J2KImageWriteParamJava(IIOImage image, ImageWriteParam param) {
super(param.getLocale());
if(image != null) {
if (image.hasRaster())
setDefaults(image.getRaster());
else
setDefaults(image.getRenderedImage());
}
setSourceRegion(param.getSourceRegion());
setSourceBands(param.getSourceBands());
try {
setTiling(param.getTileWidth(), param.getTileHeight(),
param.getTileGridXOffset(), param.getTileGridYOffset());
} catch (IllegalStateException e) {
// tileing is not set do nothing.
}
setDestinationOffset(param.getDestinationOffset());
setSourceSubsampling(param.getSourceXSubsampling(),
param.getSourceYSubsampling(),
param.getSubsamplingXOffset(),
param.getSubsamplingYOffset());
setDestinationType(param.getDestinationType());
J2KImageWriteParam j2kParam;
if(param instanceof J2KImageWriteParam) {
j2kParam = (J2KImageWriteParam)param;
} else {
j2kParam = new J2KImageWriteParam();
}
setDecompositionLevel(""+j2kParam.getNumDecompositionLevels());
setEncodingRate(j2kParam.getEncodingRate());
setLossless(j2kParam.getLossless());
setFilters(j2kParam.getFilter());
setEPH("" + j2kParam.getEPH());
setSOP("" + j2kParam.getSOP());
setProgressionName(j2kParam.getProgressionType());
int[] size = j2kParam.getCodeBlockSize();
setCodeBlockSize("" + size[0] +" " + size[1]);
enableCT = j2kParam.getComponentTransformation();
setComponentTransformation("" + enableCT);
}
/**
* Constructs a J2KImageWriteParamJava
object with default
* values for all parameters.
*/
public J2KImageWriteParamJava() {
super();
setSuperProperties();
}
/**
* Constructs a J2KImageWriteParamJava
object with default
* values for all parameters.
*/
public J2KImageWriteParamJava(RenderedImage imgsrc) {
super();
setDefaults(imgsrc);
}
/**
* Constructs a J2KImageWriteParamJava
object with default
* values for all parameters.
*/
public J2KImageWriteParamJava(Raster raster) {
super();
setDefaults(raster);
}
private void setSuperProperties() {
canOffsetTiles = true;
canWriteTiles = true;
canOffsetTiles = true;
canWriteProgressive = true;
tilingMode = MODE_EXPLICIT;
}
/** Set source */
private void setDefaults(Raster raster) {
// override the params in the super class
setSuperProperties();
if (raster != null) {
this.raster = raster;
tileGridXOffset = raster.getMinX();
tileGridYOffset = raster.getMinY();
tileWidth = raster.getWidth();
tileHeight = raster.getHeight();
tilingSet = true;
numTiles = 1;
numComponents = raster.getSampleModel().getNumBands();
}
setDefaults();
}
/** Set source */
private void setDefaults(RenderedImage imgsrc) {
// override the params in the super class
setSuperProperties();
tilingMode = MODE_EXPLICIT;
if (imgsrc != null) {
this.imgsrc = imgsrc;
tileGridXOffset = imgsrc.getTileGridXOffset();
tileGridYOffset = imgsrc.getTileGridYOffset();
tileWidth = imgsrc.getTileWidth();
tileHeight = imgsrc.getTileHeight();
tilingSet = true;
numTiles = imgsrc.getNumXTiles() * imgsrc.getNumYTiles();
numComponents = imgsrc.getSampleModel().getNumBands();
}
setDefaults();
}
private void setDefaults() {
setROIs(null);
setQuantizationType(null);
setQuantizationStep(null);
setGuardBits(null);
setFilters(null);
setDecompositionLevel(null);
setComponentTransformation(null);
setMethodForMQLengthCalc(null);
setMethodForMQTermination(null);
setCodeSegSymbol(null);
setCausalCXInfo(null);
setTerminateOnByte(null);
setResetMQ(null);
setBypass(null);
setCodeBlockSize(null);
setPrecinctPartition(null);
setSOP(null);
setEPH(null);
}
/** Sets encodingRate
*/
public void setEncodingRate(double rate) {
this.encodingRate = rate;
}
/** Gets encodingRate
*/
public double getEncodingRate() {
return encodingRate;
}
/** Sets lossless
*/
public void setLossless(boolean lossless) {
this.lossless = lossless;
}
/** Gets encodingRate
*/
public boolean getLossless() {
return lossless;
}
/** Sets packetPerTilePart
*/
public void setPacketPerTilePart(int packetPerTilePart) {
if (packetPerTilePart < 0)
throw new IllegalArgumentException(I18N.getString("J2KImageWriteParamJava0"));
this.packetPerTilePart = packetPerTilePart;
if (packetPerTilePart > 0) {
setSOP("true");
setEPH("true");
}
}
/** Gets packetPerTilePart
*/
public int getPacketPerTilePart() {
return packetPerTilePart;
}
/** Sets packPacketHeaderInTile
*/
public void setPackPacketHeaderInTile(boolean packPacketHeaderInTile) {
this.packPacketHeaderInTile = packPacketHeaderInTile;
if (packPacketHeaderInTile) {
setSOP("true");
setEPH("true");
}
}
/** Gets packPacketHeaderInTile
*/
public boolean getPackPacketHeaderInTile() {
return packPacketHeaderInTile;
}
/** Sets packPacketHeaderInMain
*/
public void setPackPacketHeaderInMain(boolean packPacketHeaderInMain) {
this.packPacketHeaderInMain = packPacketHeaderInMain;
if (packPacketHeaderInMain) {
setSOP("true");
setEPH("true");
}
}
/** Gets packPacketHeaderInMain
*/
public boolean getPackPacketHeaderInMain() {
return packPacketHeaderInMain;
}
/** Sets alignROI
*/
public void setAlignROI(boolean align) {
alignROI = align;
}
/** Gets alignROI
*/
public boolean getAlignROI() {
return alignROI;
}
/** Sets ROIs
*/
public void setROIs(String values) {
ROIs = new MaxShiftSpec(numTiles, numComponents, ModuleSpec.SPEC_TYPE_TILE_COMP, values);
}
/** Gets ROIs
*/
public MaxShiftSpec getROIs() {
return ROIs;
}
/** Sets quantizationType
*/
public void setQuantizationType(String values) {
quantizationType = new QuantTypeSpec(numTiles, numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP, this, values);
}
/** Gets quantizationType
*/
public QuantTypeSpec getQuantizationType() {
return quantizationType;
}
/** Sets quantizationStep
*/
public void setQuantizationStep(String values) {
quantizationStep = new QuantStepSizeSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
this,
values);
}
/** Gets quantizationStep
*/
public QuantStepSizeSpec getQuantizationStep() {
return quantizationStep;
}
/** Sets guardBits
*/
public void setGuardBits(String values) {
guardBits = new GuardBitsSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
this,
values);
}
/** Gets guardBits
*/
public GuardBitsSpec getGuardBits() {
return guardBits;
}
/** Sets filters
*/
// NOTE This also sets quantizationType and componentTransformation.
public void setFilters(String values) {
if (J2KImageWriteParam.FILTER_97.equals(values))
setQuantizationType ("expounded");
else
setQuantizationType("reversible");
filters = new AnWTFilterSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
(QuantTypeSpec)quantizationType,
this,
values);
setComponentTransformation(""+enableCT);
}
/** Gets filters
*/
public AnWTFilterSpec getFilters() {
return filters;
}
/** Sets decompositionLevel
*/
public void setDecompositionLevel(String values) {
decompositionLevel = new IntegerSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
this,
values,
"5");
// NOTE The precinctPartition depends upon decompositionLevel
// so it needs to be re-initialized. Note that the parameter of
// setPrecinctPartition() is not used in the current implementation.
setPrecinctPartition(null);
}
/** Gets decompositionLevel
*/
public IntegerSpec getDecompositionLevel() {
return decompositionLevel;
}
/** Sets componentTransformation
*/
// NOTE This requires filters having been set previously.
public void setComponentTransformation(String values) {
componentTransformation =
new ForwCompTransfSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE,
(AnWTFilterSpec)filters,
this,
values);
}
/** Gets componentTransformation
*/
public ForwCompTransfSpec getComponentTransformation() {
return componentTransformation;
}
/** Sets methodForMQLengthCalc
*/
public void setMethodForMQLengthCalc(String values) {
String[] strLcs = {"near_opt","lazy_good","lazy"};
methodForMQLengthCalc =
new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"near_opt",
strLcs,
this,
values);
}
/** Gets methodForMQLengthCalc
*/
public StringSpec getMethodForMQLengthCalc() {
return methodForMQLengthCalc;
}
/** Sets methodForMQTermination
*/
public void setMethodForMQTermination(String values) {
String[] strTerm = {"near_opt","easy","predict","full"};
methodForMQTermination =
new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"near_opt",
strTerm,
this,
values);
}
/** Gets methodForMQTermination
*/
public StringSpec getMethodForMQTermination() {
return methodForMQTermination;
}
/** Sets codeSegSymbol
*/
public void setCodeSegSymbol(String values) {
String[] strBoolean = {"true","false"};
codeSegSymbol =
new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"false",
strBoolean,
this,
values);
}
/** Gets codeSegSymbol
*/
public StringSpec getCodeSegSymbol() {
return codeSegSymbol;
}
/** Sets causalCXInfo
*/
public void setCausalCXInfo(String values) {
String[] strBoolean = {"true","false"};
causalCXInfo = new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"false",
strBoolean,
this,
values);
}
/** Gets causalCXInfo
*/
public StringSpec getCausalCXInfo() {
return causalCXInfo;
}
/** Sets terminateOnByte
*/
public void setTerminateOnByte(String values) {
String[] strBoolean = {"true","false"};
terminateOnByte = new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"false",
strBoolean,
this,
values);
}
/** Gets terminateOnByte
*/
public StringSpec getTerminateOnByte() {
return terminateOnByte;
}
/** Sets resetMQ
*/
public void setResetMQ(String values) {
String[] strBoolean = {"true","false"};
resetMQ = new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"false",
strBoolean,
this,
values);
}
/** Gets resetMQ
*/
public StringSpec getResetMQ() {
return resetMQ;
}
/** Sets bypass
*/
public void setBypass(String values) {
String[] strBoolean = {"true","false"};
bypass = new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"false",
strBoolean,
this,
values);
}
/** Gets bypass
*/
public StringSpec getBypass() {
return bypass;
}
/** Sets codeBlockSize
*/
public void setCodeBlockSize(String values) {
codeBlockSize = new CBlkSizeSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
this,
values);
}
/** Gets codeBlockSize
*/
public CBlkSizeSpec getCodeBlockSize() {
return codeBlockSize;
}
/** Sets precinctPartition
*/
public void setPrecinctPartition(String values) {
String[] strBoolean = {"true","false"};
if (imgsrc != null)
precinctPartition =
new PrecinctSizeSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
new RenderedImageSrc(imgsrc, this, null),
decompositionLevel,
this,
values);
else if (raster != null)
precinctPartition =
new PrecinctSizeSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
new RenderedImageSrc(raster, this, null),
decompositionLevel,
this,
values);
}
/** Gets precinctPartition
*/
public PrecinctSizeSpec getPrecinctPartition() {
return precinctPartition;
}
/** Sets SOP
*/
public void setSOP(String values) {
String[] strBoolean = {"true","false"};
SOP = new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"false",
strBoolean,
this,
values);
}
/** Gets SOP
*/
public StringSpec getSOP() {
return SOP;
}
/** Sets EPH
*/
public void setEPH(String values) {
String[] strBoolean = {"true","false"};
EPH = new StringSpec(numTiles,
numComponents,
ModuleSpec.SPEC_TYPE_TILE_COMP,
"false",
strBoolean,
this,
values);
}
/** Gets EPH
*/
public StringSpec getEPH() {
return EPH;
}
/** Sets progressionName
*/
public void setProgressionName(String values) {
progressionName = values;
}
/** Gets progressionType
*/
public String getProgressionName() {
return progressionName;
}
/** Sets progressionType
*/
public void setProgressionType(LayersInfo lyrs, String values) {
String[] strBoolean = {"true","false"};
progressionType = new ProgressionSpec(numTiles,
numComponents,
lyrs.getTotNumLayers(),
decompositionLevel,
ModuleSpec.SPEC_TYPE_TILE_COMP,
this,
values);
}
/** Gets progressionType
*/
public ProgressionSpec getProgressionType() {
return progressionType;
}
/** Sets the startLevelROI
*/
public void setStartLevelROI(int value) {
startLevelROI = value;
}
/** Gets startLevel
*/
public int getStartLevelROI() {
return startLevelROI;
}
/** Sets the layers
*/
public void setLayers(String value) {
layers = value;
}
/** Gets layers
*/
public String getLayers() {
return layers;
}
/** Sets minX
*/
public void setMinX(int minX) {
this.minX = minX;
}
/** Gets minX
*/
public int getMinX() {
return minX;
}
/** Sets minY
*/
public void setMinY(int minY) {
this.minY = minY;
}
/** Gets minY
*/
public int getMinY() {
return minY;
}
/** Gets the number of tiles */
public int getNumTiles() {
Rectangle sourceRegion = getSourceRegion();
if (sourceRegion == null) {
if (imgsrc != null)
sourceRegion = new Rectangle(imgsrc.getMinX(),
imgsrc.getMinY(),
imgsrc.getWidth(),
imgsrc.getHeight());
else sourceRegion = raster.getBounds();
} else {
if (imgsrc != null)
sourceRegion =
sourceRegion.intersection(new Rectangle(imgsrc.getMinX(),
imgsrc.getMinY(),
imgsrc.getWidth(),
imgsrc.getHeight()));
else sourceRegion = sourceRegion.intersection(raster.getBounds());
}
int scaleX = getSourceXSubsampling();
int scaleY = getSourceYSubsampling();
int xOffset = getSubsamplingXOffset();
int yOffset = getSubsamplingYOffset();
int w = (sourceRegion.width - xOffset + scaleX - 1) / scaleX;
int h = (sourceRegion.height - yOffset + scaleY - 1) / scaleY;
minX = (sourceRegion.x + xOffset) / scaleX;
minY = (sourceRegion.y + yOffset) / scaleY;
numTiles = (int)((Math.floor((minX + w + tileWidth - 1.0) / tileWidth) -
Math.floor((double)minX/tileWidth) ) *
(Math.floor((minY + h + tileHeight - 1.0) / tileHeight) -
Math.floor((double)minY/tileHeight) ) );
tileGridXOffset += (minX - tileGridXOffset) / tileWidth * tileWidth;
tileGridYOffset += (minY - tileGridYOffset) / tileHeight * tileHeight;
return numTiles;
}
/** Gets the number of components */
public int getNumComponents() {
return numComponents;
}
/** Override the method setSourceBands in the super class. This method
* should be called before any tile-specific parameter setting method
* to be called.
*/
public void setSourceBands(int[] bands) {
super.setSourceBands(bands);
if (bands != null) {
numComponents = bands.length;
setDefaults();
}
}
/** Override the method setTiling in the super class. This method
* should be called before any tile-specific parameter setting method
* to be called.
*/
public void setTiling(int tw, int th, int xOff, int yOff) {
super.setTiling(tw, th, xOff, yOff);
getNumTiles();
setDefaults();
}
/** Override the method setSourceSubsampling in the super class. This
* method should be called before any tile-specific parameter setting
* method to be called.
*/
public void setSourceSubsampling(int sx, int sy, int xOff, int yOff) {
super.setSourceSubsampling(sx, sy, xOff, yOff);
getNumTiles();
setDefaults();
}
}