0001: /*
0002: * $RCSfile: J2KImageWriteParamJava.java,v $
0003: *
0004: *
0005: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
0006: *
0007: * Redistribution and use in source and binary forms, with or without
0008: * modification, are permitted provided that the following conditions
0009: * are met:
0010: *
0011: * - Redistribution of source code must retain the above copyright
0012: * notice, this list of conditions and the following disclaimer.
0013: *
0014: * - Redistribution in binary form must reproduce the above copyright
0015: * notice, this list of conditions and the following disclaimer in
0016: * the documentation and/or other materials provided with the
0017: * distribution.
0018: *
0019: * Neither the name of Sun Microsystems, Inc. or the names of
0020: * contributors may be used to endorse or promote products derived
0021: * from this software without specific prior written permission.
0022: *
0023: * This software is provided "AS IS," without a warranty of any
0024: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
0025: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
0026: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
0027: * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
0028: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
0029: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
0030: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
0031: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
0032: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
0033: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
0034: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
0035: * POSSIBILITY OF SUCH DAMAGES.
0036: *
0037: * You acknowledge that this software is not designed or intended for
0038: * use in the design, construction, operation or maintenance of any
0039: * nuclear facility.
0040: *
0041: * $Revision: 1.2 $
0042: * $Date: 2006/09/20 23:23:30 $
0043: * $State: Exp $
0044: */
0045: package com.sun.media.imageioimpl.plugins.jpeg2000;
0046:
0047: import java.awt.Rectangle;
0048: import java.awt.image.Raster;
0049: import java.awt.image.RenderedImage;
0050: import java.util.Collections;
0051: import java.util.Locale;
0052: import java.util.Iterator;
0053: import javax.imageio.IIOImage;
0054: import javax.imageio.ImageWriteParam;
0055: import jj2000.j2k.*;
0056: import jj2000.j2k.roi.*;
0057: import jj2000.j2k.quantization.*;
0058: import jj2000.j2k.wavelet.analysis.AnWTFilterSpec;
0059: import jj2000.j2k.image.forwcomptransf.ForwCompTransfSpec;
0060: import jj2000.j2k.entropy.CBlkSizeSpec;
0061: import jj2000.j2k.entropy.PrecinctSizeSpec;
0062: import jj2000.j2k.entropy.ProgressionSpec;
0063: import jj2000.j2k.image.BlkImgDataSrc;
0064: import jj2000.j2k.entropy.encoder.LayersInfo;
0065: import com.sun.media.imageio.plugins.jpeg2000.J2KImageWriteParam;
0066:
0067: /**
0068: * A subclass of <code>ImageWriteParam</code> for writing images in
0069: * the JPEG 2000 format.
0070: *
0071: * <p>JPEG 2000 plugin supports to losslessly or lossy compress gray-scale,
0072: * RGB, and RGBA images with byte, unsigned short or short data type. It also
0073: * supports losslessly compress bilevel, and 8-bit indexed. The result data
0074: * is in the format of JP2 (JPEG 2000 Part 1 or baseline format).
0075: *
0076: * <p>Many encoding parameters for JPEG 2000 can be tile-component specific.
0077: * These parameters are marked as <code>Yes</code> in the column <code>
0078: * TC_SPEC</code> in the following parameter table.
0079: * They must be provided according to the pattern:
0080: * [<tile-component idx>] <param> (repeated as many time as needed),
0081: * where <tile-component idx> respect the following policy according to
0082: * the degree of priority:
0083: * <table>
0084: * <tr><td>(1) t<idx> c<idx> : Tile-component specification.</td></tr>
0085: * <tr><td>(2) t<idx> : Tile specification.</td></tr>
0086: * <tr><td>(3) c<idx> : Component specification.</td></tr>
0087: * <tr><td>(4) <void> : Default specification.</td></tr>
0088: * </table>
0089: * <p>Where the priorities of the specifications are:
0090: * (1) > (2) > (3) > (4), (">" means "overrides")
0091: * <idx>: "," separates indexes, "-" separates bounds of indexes list.
0092: * (for example, 0,2-4 means indexes 0,2,3 and 4).
0093: *
0094: * <p>The parameters for encoding JPEG 2000 are listed in the following table:
0095: *
0096: * * <p><table border=1>
0097: * <caption><b>JPEG 2000 Plugin Decoding Parameters</b></caption>
0098: * <tr><th>Parameter Name</th> <th>Description</th><th>TC_SPEC</th></tr>
0099: * <tr>
0100: * <td>encodingRate</td>
0101: * <td> The bitrate in bits-per-pixel for encoding. Should be set when
0102: * lossy compression scheme is used. With the default value
0103: * <code>Double.MAX_VALUE</code>, a lossless compression will be done.
0104: * </td>
0105: * <td>No</td>
0106: * </tr>
0107: * <tr>
0108: * <td>lossless</td>
0109: * <td> Indicates using the loseless scheme or not. It is equivalent to
0110: * use reversible quantization and 5x3 integer wavelet filters. The
0111: * default is <code>true</code>.
0112: * </td>
0113: * <td>No</td>
0114: * </tr>
0115: * <tr>
0116: * <td>componentTransformation</td>
0117: * <td> Specifies to utilize the component transformation on some tiles.
0118: * If the wavelet transform is reversible (w5x3 filter), the Reversible
0119: * Component Transformation (RCT) is applied. If not reversible
0120: * (w9x7 filter), the Irreversible Component Transformation (ICT) is used.
0121: * </td>
0122: * <td>Yes, Tile_Specific</td>
0123: * </tr>
0124: * <tr>
0125: * <td>filters</td>
0126: * <td> Specifies which wavelet filters to use for the specified
0127: * tile-components. JPEG 2000 part I only supports w5x3 and w9x7 filters.
0128: * </td>
0129: * <td>Yes</td>
0130: * </tr>
0131: * <tr>
0132: * <td>decompositionLevel</td>
0133: * <td> Specifies the wavelet decomposition levels to apply to
0134: * the image. If it is 0, no wavelet transform is performed, in which
0135: * case the original image data will be sent to the encoder and an example
0136: * is the binary data. All components and all tiles have the same number
0137: * of decomposition levels. The default value is 5.
0138: * </td>
0139: * <td>No</td>
0140: * </tr>
0141: * <tr>
0142: * <td>guardBits</td>
0143: * <td> The number of bits used for each tile-component in the quantizer
0144: * to avoid overflow. It takes values in the range 0 through 7. The
0145: * default value is 2.
0146: * </td>
0147: * <td>Yes</td>
0148: * </tr>
0149: * <tr>
0150: * <td>quantizationStep</td>
0151: * <td> This parameter specifies the base normalized quantization step
0152: * size for the tiles/components. It is normalized to a dynamic range
0153: * of 1 in the image domain. This parameter is ignored in reversible
0154: * coding. The default value is 0.0078125.
0155: * </td>
0156: * <td>Yes</td>
0157: * </tr>
0158: * <tr>
0159: * <td>quantizationType</td>
0160: * <td> Specifies which quantization type to use for specified
0161: * tiles/components. Not specified for lossless compression. By default,
0162: * the quantization step size is "expounded". Supported quantization
0163: * types specification are : "reversible" (no quantization), "derived"
0164: * (derived quantization step size) and "expounded".
0165: * </td>
0166: * <td>Yes</td>
0167: * </tr>
0168: * <tr>
0169: * <td>codeBlockSize</td>
0170: * <td> Specifies the maximum code-block size to use for tile-component.
0171: * The maximum width and height is 1024, however the block size
0172: * (i.e. width x height) must not exceed 4096. The minimum width and
0173: * height is 4. The default values are (64, 64).
0174: * </td>
0175: * <td>Yes</td>
0176: * </tr>
0177: * <tr>
0178: * <td>progressionType</td>
0179: * <td> Specifies which type of progression should be used when generating
0180: * the codestream.
0181: * <p> The format is [<tile index>]
0182: * res|layer|res-pos|pos-comp|comp-pos [res_start comp_start layer_end
0183: * res_end comp_end prog] [[res_start comp_start layer_end res_end
0184: * comp_end prog]...] [[<tile-component idx]...].
0185: * <p>The value "res" generates a resolution progressive
0186: * codestream with the number of layers specified by "layers" parameter.
0187: * The value "layer" generates a layer progressive codestream with
0188: * multiple layers. In any case, the rate-allocation algorithm optimizes
0189: * for best quality in each layer. The quality measure is mean squared
0190: * error (MSE) or a weighted version of it (WMSE). If no progression
0191: * type is specified or imposed by other parameters, the default value
0192: * is "layer". It is also possible to describe progression order
0193: * changes. In this case, "res_start" is the index (from 0) of the
0194: * first resolution level, "comp_start" is the index (from 0) of the
0195: * first component, "layer_end" is the index (from 0) of the first layer
0196: * not included, "res_end" is the index (from 0) of the first
0197: * resolution level not included, "comp_end" is index (from 0) of
0198: * the first component not included and "prog" is the progression type
0199: * to be used for the rest of the tile/image. Several progression
0200: * order changes can be specified, one after the other.
0201: * </td>
0202: * <td>Yes</td>
0203: * </tr>
0204: * <tr>
0205: * <td>packPacketHeaderInTile</td>
0206: * <td> Indicates that the packet headers are packed in the tiles' headers.
0207: * The default is false.
0208: * </td>
0209: * <td>No</td>
0210: * </tr>
0211: * <tr>
0212: * <td>packPacketHeaderInMain</td>
0213: * <td> Indicates that the packet headers are packed in the main header.
0214: * The default is false.
0215: * </td>
0216: * <td>No</td>
0217: * </tr>
0218: * <tr>
0219: * <td>packetPerTilePart</td>
0220: * <td> Specifies the maximum number of packets to be put into one tile-part.
0221: * Zero means putting all packets in the first tile-part of each tile.
0222: * </td>
0223: * <td>No</td>
0224: * </tr>
0225: * <tr>
0226: * <td>ROIs</td>
0227: * <td> Specifies ROIs shape and location. The component index specifies
0228: * which components contain the ROI. If this parameter is used, the
0229: * codestream is layer progressive by default unless it is overridden by
0230: * the <code>progressionType</code>. A rectanglar or circular ROI can be
0231: * specified in the format: [<component idx>] R <left>
0232: * <top> <width> <height> or [<component idx>] C
0233: * <center x> <center y> <radius>. An arbitrary shape
0234: * can be assigned by [<component idx>] A <PGM file>
0235: * </td>
0236: * <td>Yes, component-specified</td>
0237: * </tr>
0238: * <tr>
0239: * <td>startLevelROI</td>
0240: * <td> This parameter defines the lowest resolution levels to belong to
0241: * the ROI. By doing this, it is possible to avoid getting
0242: * information for the ROI at an early stage of transmission.
0243: * startLevelROI = 0 means the lowest resolution level belongs to
0244: * the ROI, 1 means the second lowest etc. The default values, -1,
0245: * deactivates this parameter.
0246: * </td>
0247: * <td>No</td>
0248: * </tr>
0249: * <tr>
0250: * <td>alignROI</td>
0251: * <td> By specifying this parameter, the ROI mask will be limited to
0252: * covering only entire code-blocks. The ROI coding can then be
0253: * performed without any actual scaling of the coefficients but by
0254: * instead scaling the distortion estimates.
0255: * </td>
0256: * <td>No</td>
0257: * </tr>
0258: * <tr>
0259: * <td>bypass</td>
0260: * <td> Uses the lazy coding mode with the entropy coder. This will bypass
0261: * the MQ coder for some of the coding passes, where the distribution
0262: * is often close to uniform. Since the MQ codeword will be terminated
0263: * at least once per lazy pass, it is important to use an efficient
0264: * termination algorithm, <code>methodForMQTermination</code>.
0265: * true enables, and false disables it. The default value is false.
0266: * </td>
0267: * <td>Yes</td>
0268: * </tr>
0269: * <tr>
0270: * <td>resetMQ</td>
0271: * <td> If this is enabled the probability estimates of the MQ coder are
0272: * reset after each arithmetically coded (i.e. non-lazy) coding pass.
0273: * true enables, and false disables it. The default value is false.
0274: * </td>
0275: * <td>Yes</td>
0276: * </tr>
0277: * <tr>
0278: * <td>terminateOnByte</td>
0279: * <td> If this is enabled the codeword (raw or MQ) is terminated on a byte
0280: * boundary after each coding pass. In this case it is important to use
0281: * an efficient termination algorithm, "methodForMQTermination".
0282: * true enables, and false disables it. The default value is false.
0283: * </td>
0284: * <td>Yes</td>
0285: * </tr>
0286: * <tr>
0287: * <td>causalCXInfo</td>
0288: * <td> Uses vertically stripe causal context formation. If this is
0289: * enabled the context formation process in one stripe is independant of
0290: * the next stripe (i.e. the one below it). true enables, and false
0291: * disables it. The default value is false.
0292: * </td>
0293: * <td>Yes</td>
0294: * </tr>
0295: * <tr>
0296: * <td>codeSegSymbol</td>
0297: * <td> Inserts an error resilience segmentation symbol in the MQ codeword
0298: * at the end of each bit-plane (cleanup pass). Decoders can use this
0299: * information to detect and conceal errors. true enables, and false
0300: * disables it. The default value is false.
0301: * </td>
0302: * <td>Yes</td>
0303: * </tr>
0304: * <tr>
0305: * <td>methodForMQTermination</td>
0306: * <td> Specifies the algorithm used to terminate the MQ codeword. The
0307: * most efficient one is "near_opt", which delivers a codeword which
0308: * in almost all cases is the shortest possible. The "easy" is a
0309: * simpler algorithm that delivers a codeword length that is close
0310: * to the previous one (in average 1 bit longer). The "predict" is
0311: * almost the same as the "easy" but it leaves error resilient
0312: * information on the spare least significant bits (in average 3.5 bits),
0313: * which can be used by a decoder to detect errors. The "full" algorithm
0314: * performs a full flush of the MQ coder and is highly inefficient. It
0315: * is important to use a good termination policy since the MQ codeword
0316: * can be terminated quite often, specially if the "bypass" or
0317: * "terminateOnByte" parameters are enabled (in the normal case it would
0318: * be terminated once per code-block, while "terminateOnByte" is specified
0319: * it will be done almost 3 times per bit-plane in each code-block).
0320: * The default value is "near_opt".
0321: * </td>
0322: * <td>Yes</td>
0323: * </tr>
0324: * <tr>
0325: * <td>methodForMQLengthCalc</td>
0326: * <td> Specifies the algorithm to use in calculating the necessary MQ
0327: * length for each decoding pass. The best one is "near_opt", which
0328: * performs a rather sophisticated calculation and provides the best
0329: * results. The "lazy_good" and "lazy" are very simple algorithms
0330: * that provide rather conservative results. "lazy_good" performs
0331: * slightly better. Please use the default unless the experiments
0332: * show the benefits of different length calculation algorithms.
0333: * The default value is "near_opt".
0334: * </td>
0335: * <td>Yes</td>
0336: * </tr>
0337: * <tr>
0338: * <td>precinctPartition</td>
0339: * <td> Specifies precinct partition dimensions for tiles/components. They
0340: * are stored from those applied to the highest resolution to those
0341: * applied to the remaining resolutions in decreasing order. If less
0342: * values than the number of decomposition levels are specified, then
0343: * the last two values are used for the remaining resolutions.
0344: * </td>
0345: * <td>Yes</td>
0346: * </tr>
0347: * <tr>
0348: * <td>layers</td>
0349: * <td> Explicitly specifies the codestream layer formation parameters.
0350: * The rate (double) parameter specifies the bitrate to which the first
0351: * layer should be optimized. The layers (int) parameter, if present,
0352: * specifies the number of extra layers that should be added for
0353: * scalability. These extra layers are not optimized. Any extra rate
0354: * and layers parameters add more layers, in the same way. An
0355: * additional layer is always added at the end, which is optimized
0356: * to the overall target bitrate of the bit stream. Any layers
0357: * (optimized or not) whose target bitrate is higher that the overall
0358: * target bitrate are silently ignored. The bitrates of the extra layers
0359: * that are added through the layers parameter are approximately
0360: * log-spaced between the other target bitrates. If several (rate, layers)
0361: * constructs appear the rate parameters must appear in increasing order.
0362: * The rate allocation algorithm ensures that all coded layers have a
0363: * minimal reasonable size, if not these layers are silently ignored.
0364: * Default: 0.015 +20 2.0 +10.
0365: * </td>
0366: * <td>No</td>
0367: * </tr>
0368: * <tr>
0369: * <td>SOP</td>
0370: * <td>Specifies whether start of packet (SOP) markers should be used.
0371: * true enables, false disables it. The default value is false.
0372: * </td>
0373: * <td>Yes</td>
0374: * </tr>
0375: * <tr>
0376: * <td>EPH</td>
0377: * <td>Specifies whether end of packet header (EPH) markers should be used.
0378: * true enables, false disables it. The default value is false.
0379: * </td>
0380: * <td>Yes</td>
0381: * </tr>
0382: * </table>
0383: */
0384: public class J2KImageWriteParamJava extends ImageWriteParam {
0385: /**
0386: * Indicates that the packet headers are packed in the tiles' headers.
0387: */
0388: private boolean packPacketHeaderInTile = false;
0389:
0390: /**
0391: * Indicates that the packet headers are packed in the main header.
0392: */
0393: private boolean packPacketHeaderInMain = false;
0394:
0395: /**
0396: * Specifies the maximum number of packets to be put into one tile-part.
0397: * Zero means include all packets in first tile-part of each tile.
0398: */
0399: private int packetPerTilePart = 0;
0400:
0401: /**
0402: * The bitrate in bits-per-pixel for encoding. Should be set when lossy
0403: * compression scheme is used. The default is
0404: * <code>Double.MAX_VALUE</code>.
0405: */
0406: private double encodingRate = Double.MAX_VALUE;
0407:
0408: /**
0409: * Indicates using the loseless scheme or not. It is equivalent to
0410: * use reversible quantization and 5x3 integer wavelet filters.
0411: */
0412: private boolean lossless = true;
0413:
0414: /** Specifies to utilize the component transformation with some tiles.
0415: * If the wavelet transform is reversible (w5x3 filter), the
0416: * Reversible Component Transformation (RCT) is applied. If not reversible
0417: * (w9x7 filter), the Irreversible Component Transformation (ICT)
0418: * is used.
0419: */
0420: private ForwCompTransfSpec componentTransformation = null;
0421: private boolean enableCT = true;
0422:
0423: /** Specifies which filters to use for the specified tile-components.
0424: * JPEG 2000 part I only supports w5x3 and w9x7 filters.
0425: */
0426: private AnWTFilterSpec filters = null;
0427:
0428: /** Specifies the number of wavelet decomposition levels to apply to
0429: * the image. If it is 0, no wavelet transform is performed, in which
0430: * case the original image data will be sent to the encoder and an
0431: * example is the binary data. All components and all tiles have
0432: * the same number of decomposition levels. Default: 5.
0433: */
0434: private IntegerSpec decompositionLevel = null; // = 5;
0435:
0436: /** The number of bits used for each tile-component in
0437: * the quantizer to avoid overflow. It takes values in the range 0
0438: * through 7. Default: 2.
0439: */
0440: private GuardBitsSpec guardBits = null;
0441:
0442: /** This parameter specifies the base normalized quantization step
0443: * size for the tiles/components. It is normalized to a dynamic range
0444: * of 1 in the image domain. This parameter is ignored in reversible
0445: * coding. Default: 0.0078125.
0446: */
0447: private QuantStepSizeSpec quantizationStep = null;
0448:
0449: /** Specifies which quantization type to use for specified
0450: * tiles/components. Not specified for lossless compression. By
0451: * default , the quantization step size is "expounded". Supported
0452: * quantization types specification are : "reversible" (no quantization),
0453: * "derived" (derived quantization step size) and "expounded".
0454: */
0455: private QuantTypeSpec quantizationType = null;
0456:
0457: /** This parameter defines the lowest resolution levels to belong to
0458: * the ROI. By doing this, it is possible to avoid only getting
0459: * information for the ROI at an early stage of transmission.
0460: * startLevelROI = 0 means the lowest resolution level belongs to
0461: * the ROI, 1 means the second lowest etc. The default values, -1,
0462: * deactivates this parameter.
0463: */
0464: private int startLevelROI = -1;
0465:
0466: /** By specifying this parameter, the ROI mask will be limited to
0467: * covering only entire code-blocks. The ROI coding can then be
0468: * performed without any actual scaling of the coefficients but
0469: * by instead scaling the distortion estimates.
0470: */
0471: private boolean alignROI = false;
0472:
0473: /** Specifies ROIs shape and location. The component index specifies
0474: * which components contain the ROI. If this parameter is used, the
0475: * codestream is layer progressive by default unless it is
0476: * overridden by the <code>progressionType</code>.
0477: */
0478: private MaxShiftSpec ROIs = null;
0479:
0480: /** Specifies the maximum code-block size to use for tile-component.
0481: * The maximum width and height is 1024, however the image area
0482: * (i.e. width x height) must not exceed 4096. The minimum
0483: * width and height is 4. Default: 64 64.
0484: */
0485: private CBlkSizeSpec codeBlockSize = null;
0486:
0487: /** Uses the lazy coding mode with the entropy coder. This will bypass
0488: * the MQ coder for some of the coding passes, where the distribution
0489: * is often close to uniform. Since the MQ codeword will be terminated
0490: * at least once per lazy pass, it is important to use an efficient
0491: * termination algorithm, <code>methodForMQTermination</code>.
0492: * true enables, and false disables it. Default: false.
0493: */
0494: private StringSpec bypass = null;
0495:
0496: /** If this is enabled the probability estimates of the MQ coder are
0497: * reset after each arithmetically coded (i.e. non-lazy) coding pass.
0498: * true enables, and false disables it. Default: false.
0499: */
0500: private StringSpec resetMQ = null;
0501:
0502: /** If this is enabled the codeword (raw or MQ) is terminated on a byte
0503: * boundary after each coding pass. In this case it is important to
0504: * use an efficient termination algorithm, the "methodForMQTermination".
0505: * true enables, and false disables it. Default: false.
0506: */
0507: private StringSpec terminateOnByte = null;
0508:
0509: /** Uses vertically stripe causal context formation. If this is
0510: * enabled the context formation process in one stripe is independant
0511: * of the next stripe (i.e. the one below it). true enables, and
0512: * false disables it. Default: false.
0513: */
0514: private StringSpec causalCXInfo = null;
0515:
0516: /** Inserts an error resilience segmentation symbol in the MQ codeword
0517: * at the end of each bit-plane (cleanup pass). Decoders can use this
0518: * information to detect and conceal errors. true enables,
0519: * and false disables it. Default: false.
0520: */
0521: private StringSpec codeSegSymbol = null;
0522:
0523: /** Specifies the algorithm used to terminate the MQ codeword. The
0524: * most efficient one is "near_opt", which delivers a codeword which
0525: * in almost all cases is the shortest possible. The "easy" is a
0526: * simpler algorithm that delivers a codeword length that is close
0527: * to the previous one (in average 1 bit longer). The "predict" is
0528: * almost the same as the "easy" but it leaves error resilient
0529: * information on the spare least significant bits (in average
0530: * 3.5 bits), which can be used by a decoder to detect errors.
0531: * The "full" algorithm performs a full flush of the MQ coder and
0532: * is highly inefficient. It is important to use a good termination
0533: * policy since the MQ codeword can be terminated quite often,
0534: * specially if the "bypass" or "terminateOnByte" parameters are
0535: * enabled (in the normal case it would be terminated once per
0536: * code-block, while "terminateOnByte" is specified it will be
0537: * done almost 3 times per bit-plane in each code-block).
0538: * Default: near_opt.
0539: */
0540: private StringSpec methodForMQTermination = null;
0541:
0542: /** Specifies the algorithm to use in calculating the necessary MQ
0543: * length for each decoding pass. The best one is "near_opt", which
0544: * performs a rather sophisticated calculation and provides the best
0545: * results. The "lazy_good" and "lazy" are very simple algorithms
0546: * that provide rather conservative results. "lazy_good" performs
0547: * slightly better. Please use the default unless the experiments
0548: * show the benefits of different length calculation algorithms.
0549: * Default: near_opt.
0550: */
0551: private StringSpec methodForMQLengthCalc = null;
0552:
0553: /** Specifies precinct partition dimensions for tiles/components. They
0554: * are stored from those applied to the highest resolution to those
0555: * applied to the remaining resolutions in decreasing order. If less
0556: * values than the number of decomposition levels are specified, then
0557: * the last two values are used for the remaining resolutions.
0558: */
0559: private PrecinctSizeSpec precinctPartition = null;
0560:
0561: /** Specifies which type of progression should be used when generating
0562: * the codestream. The value "res" generates a resolution progressive
0563: * codestream with the number of layers specified by "layers" parameter.
0564: * The value "layer" generates a layer progressive codestream with
0565: * multiple layers. In any case, the rate-allocation algorithm optimizes
0566: * for best quality in each layer. The quality measure is mean squared
0567: * error (MSE) or a weighted version of it (WMSE). If no progression
0568: * type is specified or imposed by other modules, the default value
0569: * is "layer". It is also possible to describe progression order
0570: * changes. In this case, "res_start" is the index (from 0) of the
0571: * first resolution level, "comp_start" is the index (from 0) of the
0572: * first component, "ly_end" is the index (from 0) of the first layer
0573: * not included, "res_end" is the index (from 0) of the first
0574: * resolution level not included, "comp_end" is index (from 0) of
0575: * the first component not included and "prog" is the progression type
0576: * to be used for the rest of the tile/image. Several progression
0577: * order changes can be specified, one after the other.
0578: */
0579: private ProgressionSpec progressionType = null;
0580:
0581: /**
0582: * The specified (tile-component) progression. Will be used to generate
0583: * the progression type.
0584: */
0585: private String progressionName = null;
0586:
0587: /** Explicitly specifies the codestream layer formation parameters.
0588: * The rate (double) parameter specifies the bitrate to which the first
0589: * layer should be optimized. The layers (int) parameter, if present,
0590: * specifies the number of extra layers that should be added for
0591: * scalability. These extra layers are not optimized. Any extra rate
0592: * and layers parameters add more layers, in the same way. An
0593: * additional layer is always added at the end, which is optimized
0594: * to the overall target bitrate of the bit stream. Any layers
0595: * (optimized or not) whose target bitrate is higher that the
0596: * overall target bitrate are silently ignored. The bitrates of
0597: * the extra layers that are added through the layers parameter
0598: * are approximately log-spaced between the other target bitrates.
0599: * If several (rate, layers) constructs appear the rate parameters
0600: * must appear in increasing order. The rate allocation algorithm
0601: * ensures that all coded layers have a minimal reasonable size,
0602: * if not these layers are silently ignored. Default: 0.015 +20 2.0 +10.
0603: */
0604: private String layers = "0.015 +20 2.0 +10";
0605:
0606: /** Specifies whether end of packet header (EPH) markers should be used.
0607: * true enables, false disables it. Default: false.
0608: */
0609: private StringSpec EPH = null;
0610:
0611: /** Specifies whether start of packet (SOP) markers should be used.
0612: * true enables, false disables it. Default: false.
0613: */
0614: private StringSpec SOP = null;
0615:
0616: private int numTiles;
0617: private int numComponents;
0618:
0619: private RenderedImage imgsrc;
0620: private Raster raster;
0621:
0622: private int minX;
0623: private int minY;
0624:
0625: /** Constructor to set locales. */
0626: public J2KImageWriteParamJava(RenderedImage imgsrc, Locale locale) {
0627: super (locale);
0628: setDefaults(imgsrc);
0629: }
0630:
0631: /** Constructor to set locales. */
0632: public J2KImageWriteParamJava(IIOImage image, ImageWriteParam param) {
0633: super (param.getLocale());
0634: if (image != null) {
0635: if (image.hasRaster())
0636: setDefaults(image.getRaster());
0637: else
0638: setDefaults(image.getRenderedImage());
0639: }
0640:
0641: setSourceRegion(param.getSourceRegion());
0642: setSourceBands(param.getSourceBands());
0643: try {
0644: setTiling(param.getTileWidth(), param.getTileHeight(),
0645: param.getTileGridXOffset(), param
0646: .getTileGridYOffset());
0647: } catch (IllegalStateException e) {
0648: // tileing is not set do nothing.
0649: }
0650:
0651: setDestinationOffset(param.getDestinationOffset());
0652: setSourceSubsampling(param.getSourceXSubsampling(), param
0653: .getSourceYSubsampling(),
0654: param.getSubsamplingXOffset(), param
0655: .getSubsamplingYOffset());
0656: setDestinationType(param.getDestinationType());
0657:
0658: J2KImageWriteParam j2kParam;
0659: if (param instanceof J2KImageWriteParam) {
0660: j2kParam = (J2KImageWriteParam) param;
0661: } else {
0662: j2kParam = new J2KImageWriteParam();
0663: }
0664:
0665: setDecompositionLevel("" + j2kParam.getNumDecompositionLevels());
0666: setEncodingRate(j2kParam.getEncodingRate());
0667: setLossless(j2kParam.getLossless());
0668: setFilters(j2kParam.getFilter());
0669: setEPH("" + j2kParam.getEPH());
0670: setSOP("" + j2kParam.getSOP());
0671: setProgressionName(j2kParam.getProgressionType());
0672: int[] size = j2kParam.getCodeBlockSize();
0673: setCodeBlockSize("" + size[0] + " " + size[1]);
0674: enableCT = j2kParam.getComponentTransformation();
0675: setComponentTransformation("" + enableCT);
0676: }
0677:
0678: /**
0679: * Constructs a <code>J2KImageWriteParamJava</code> object with default
0680: * values for all parameters.
0681: */
0682: public J2KImageWriteParamJava() {
0683: super ();
0684: setSuperProperties();
0685: }
0686:
0687: /**
0688: * Constructs a <code>J2KImageWriteParamJava</code> object with default
0689: * values for all parameters.
0690: */
0691: public J2KImageWriteParamJava(RenderedImage imgsrc) {
0692: super ();
0693: setDefaults(imgsrc);
0694: }
0695:
0696: /**
0697: * Constructs a <code>J2KImageWriteParamJava</code> object with default
0698: * values for all parameters.
0699: */
0700: public J2KImageWriteParamJava(Raster raster) {
0701: super ();
0702: setDefaults(raster);
0703: }
0704:
0705: private void setSuperProperties() {
0706: canOffsetTiles = true;
0707: canWriteTiles = true;
0708: canOffsetTiles = true;
0709: canWriteProgressive = true;
0710: tilingMode = MODE_EXPLICIT;
0711: }
0712:
0713: /** Set source */
0714: private void setDefaults(Raster raster) {
0715: // override the params in the super class
0716: setSuperProperties();
0717:
0718: if (raster != null) {
0719: this .raster = raster;
0720: tileGridXOffset = raster.getMinX();
0721: tileGridYOffset = raster.getMinY();
0722: tileWidth = raster.getWidth();
0723: tileHeight = raster.getHeight();
0724: tilingSet = true;
0725:
0726: numTiles = 1;
0727: numComponents = raster.getSampleModel().getNumBands();
0728: }
0729: setDefaults();
0730: }
0731:
0732: /** Set source */
0733: private void setDefaults(RenderedImage imgsrc) {
0734: // override the params in the super class
0735: setSuperProperties();
0736:
0737: tilingMode = MODE_EXPLICIT;
0738:
0739: if (imgsrc != null) {
0740: this .imgsrc = imgsrc;
0741: tileGridXOffset = imgsrc.getTileGridXOffset();
0742: tileGridYOffset = imgsrc.getTileGridYOffset();
0743: tileWidth = imgsrc.getTileWidth();
0744: tileHeight = imgsrc.getTileHeight();
0745: tilingSet = true;
0746:
0747: numTiles = imgsrc.getNumXTiles() * imgsrc.getNumYTiles();
0748: numComponents = imgsrc.getSampleModel().getNumBands();
0749: }
0750: setDefaults();
0751: }
0752:
0753: private void setDefaults() {
0754: setROIs(null);
0755: setQuantizationType(null);
0756: setQuantizationStep(null);
0757: setGuardBits(null);
0758: setFilters(null);
0759: setDecompositionLevel(null);
0760: setComponentTransformation(null);
0761: setMethodForMQLengthCalc(null);
0762: setMethodForMQTermination(null);
0763: setCodeSegSymbol(null);
0764: setCausalCXInfo(null);
0765: setTerminateOnByte(null);
0766: setResetMQ(null);
0767: setBypass(null);
0768: setCodeBlockSize(null);
0769: setPrecinctPartition(null);
0770: setSOP(null);
0771: setEPH(null);
0772: }
0773:
0774: /** Sets <code>encodingRate</code> */
0775: public void setEncodingRate(double rate) {
0776: this .encodingRate = rate;
0777: }
0778:
0779: /** Gets <code>encodingRate</code> */
0780: public double getEncodingRate() {
0781: return encodingRate;
0782: }
0783:
0784: /** Sets <code>lossless</code> */
0785: public void setLossless(boolean lossless) {
0786: this .lossless = lossless;
0787: }
0788:
0789: /** Gets <code>encodingRate</code> */
0790: public boolean getLossless() {
0791: return lossless;
0792: }
0793:
0794: /** Sets <code>packetPerTilePart</code> */
0795: public void setPacketPerTilePart(int packetPerTilePart) {
0796: if (packetPerTilePart < 0)
0797: throw new IllegalArgumentException(I18N
0798: .getString("J2KImageWriteParamJava0"));
0799:
0800: this .packetPerTilePart = packetPerTilePart;
0801: if (packetPerTilePart > 0) {
0802: setSOP("true");
0803: setEPH("true");
0804: }
0805: }
0806:
0807: /** Gets <code>packetPerTilePart</code> */
0808: public int getPacketPerTilePart() {
0809: return packetPerTilePart;
0810: }
0811:
0812: /** Sets <code>packPacketHeaderInTile</code> */
0813: public void setPackPacketHeaderInTile(boolean packPacketHeaderInTile) {
0814: this .packPacketHeaderInTile = packPacketHeaderInTile;
0815: if (packPacketHeaderInTile) {
0816: setSOP("true");
0817: setEPH("true");
0818: }
0819: }
0820:
0821: /** Gets <code>packPacketHeaderInTile</code> */
0822: public boolean getPackPacketHeaderInTile() {
0823: return packPacketHeaderInTile;
0824: }
0825:
0826: /** Sets <code>packPacketHeaderInMain</code> */
0827: public void setPackPacketHeaderInMain(boolean packPacketHeaderInMain) {
0828: this .packPacketHeaderInMain = packPacketHeaderInMain;
0829: if (packPacketHeaderInMain) {
0830: setSOP("true");
0831: setEPH("true");
0832: }
0833: }
0834:
0835: /** Gets <code>packPacketHeaderInMain</code> */
0836: public boolean getPackPacketHeaderInMain() {
0837: return packPacketHeaderInMain;
0838: }
0839:
0840: /** Sets <code>alignROI</code> */
0841: public void setAlignROI(boolean align) {
0842: alignROI = align;
0843: }
0844:
0845: /** Gets <code>alignROI</code> */
0846: public boolean getAlignROI() {
0847: return alignROI;
0848: }
0849:
0850: /** Sets <code>ROIs</code> */
0851: public void setROIs(String values) {
0852: ROIs = new MaxShiftSpec(numTiles, numComponents,
0853: ModuleSpec.SPEC_TYPE_TILE_COMP, values);
0854: }
0855:
0856: /** Gets <code>ROIs</code> */
0857: public MaxShiftSpec getROIs() {
0858: return ROIs;
0859: }
0860:
0861: /** Sets <code>quantizationType</code> */
0862: public void setQuantizationType(String values) {
0863: quantizationType = new QuantTypeSpec(numTiles, numComponents,
0864: ModuleSpec.SPEC_TYPE_TILE_COMP, this , values);
0865: }
0866:
0867: /** Gets <code>quantizationType</code> */
0868: public QuantTypeSpec getQuantizationType() {
0869: return quantizationType;
0870: }
0871:
0872: /** Sets <code>quantizationStep</code> */
0873: public void setQuantizationStep(String values) {
0874: quantizationStep = new QuantStepSizeSpec(numTiles,
0875: numComponents, ModuleSpec.SPEC_TYPE_TILE_COMP, this ,
0876: values);
0877: }
0878:
0879: /** Gets <code>quantizationStep</code> */
0880: public QuantStepSizeSpec getQuantizationStep() {
0881: return quantizationStep;
0882: }
0883:
0884: /** Sets <code>guardBits</code> */
0885: public void setGuardBits(String values) {
0886: guardBits = new GuardBitsSpec(numTiles, numComponents,
0887: ModuleSpec.SPEC_TYPE_TILE_COMP, this , values);
0888: }
0889:
0890: /** Gets <code>guardBits</code> */
0891: public GuardBitsSpec getGuardBits() {
0892: return guardBits;
0893: }
0894:
0895: /** Sets <code>filters</code> */
0896: // NOTE This also sets quantizationType and componentTransformation.
0897: public void setFilters(String values) {
0898: if (J2KImageWriteParam.FILTER_97.equals(values))
0899: setQuantizationType("expounded");
0900: else
0901: setQuantizationType("reversible");
0902:
0903: filters = new AnWTFilterSpec(numTiles, numComponents,
0904: ModuleSpec.SPEC_TYPE_TILE_COMP,
0905: (QuantTypeSpec) quantizationType, this , values);
0906: setComponentTransformation("" + enableCT);
0907: }
0908:
0909: /** Gets <code>filters</code> */
0910: public AnWTFilterSpec getFilters() {
0911: return filters;
0912: }
0913:
0914: /** Sets <code>decompositionLevel</code> */
0915: public void setDecompositionLevel(String values) {
0916: decompositionLevel = new IntegerSpec(numTiles, numComponents,
0917: ModuleSpec.SPEC_TYPE_TILE_COMP, this , values, "5");
0918:
0919: // NOTE The precinctPartition depends upon decompositionLevel
0920: // so it needs to be re-initialized. Note that the parameter of
0921: // setPrecinctPartition() is not used in the current implementation.
0922: setPrecinctPartition(null);
0923: }
0924:
0925: /** Gets <code>decompositionLevel</code> */
0926: public IntegerSpec getDecompositionLevel() {
0927: return decompositionLevel;
0928: }
0929:
0930: /** Sets <code>componentTransformation</code> */
0931: // NOTE This requires filters having been set previously.
0932: public void setComponentTransformation(String values) {
0933: componentTransformation = new ForwCompTransfSpec(numTiles,
0934: numComponents, ModuleSpec.SPEC_TYPE_TILE,
0935: (AnWTFilterSpec) filters, this , values);
0936: }
0937:
0938: /** Gets <code>componentTransformation</code> */
0939: public ForwCompTransfSpec getComponentTransformation() {
0940: return componentTransformation;
0941: }
0942:
0943: /** Sets <code>methodForMQLengthCalc</code> */
0944: public void setMethodForMQLengthCalc(String values) {
0945: String[] strLcs = { "near_opt", "lazy_good", "lazy" };
0946: methodForMQLengthCalc = new StringSpec(numTiles, numComponents,
0947: ModuleSpec.SPEC_TYPE_TILE_COMP, "near_opt", strLcs,
0948: this , values);
0949: }
0950:
0951: /** Gets <code>methodForMQLengthCalc</code> */
0952: public StringSpec getMethodForMQLengthCalc() {
0953: return methodForMQLengthCalc;
0954: }
0955:
0956: /** Sets <code>methodForMQTermination</code> */
0957: public void setMethodForMQTermination(String values) {
0958: String[] strTerm = { "near_opt", "easy", "predict", "full" };
0959: methodForMQTermination = new StringSpec(numTiles,
0960: numComponents, ModuleSpec.SPEC_TYPE_TILE_COMP,
0961: "near_opt", strTerm, this , values);
0962: }
0963:
0964: /** Gets <code>methodForMQTermination</code> */
0965: public StringSpec getMethodForMQTermination() {
0966: return methodForMQTermination;
0967: }
0968:
0969: /** Sets <code>codeSegSymbol</code> */
0970: public void setCodeSegSymbol(String values) {
0971: String[] strBoolean = { "true", "false" };
0972: codeSegSymbol = new StringSpec(numTiles, numComponents,
0973: ModuleSpec.SPEC_TYPE_TILE_COMP, "false", strBoolean,
0974: this , values);
0975: }
0976:
0977: /** Gets <code>codeSegSymbol</code> */
0978: public StringSpec getCodeSegSymbol() {
0979: return codeSegSymbol;
0980: }
0981:
0982: /** Sets <code>causalCXInfo</code> */
0983: public void setCausalCXInfo(String values) {
0984: String[] strBoolean = { "true", "false" };
0985: causalCXInfo = new StringSpec(numTiles, numComponents,
0986: ModuleSpec.SPEC_TYPE_TILE_COMP, "false", strBoolean,
0987: this , values);
0988: }
0989:
0990: /** Gets <code>causalCXInfo</code> */
0991: public StringSpec getCausalCXInfo() {
0992: return causalCXInfo;
0993: }
0994:
0995: /** Sets <code>terminateOnByte</code> */
0996: public void setTerminateOnByte(String values) {
0997: String[] strBoolean = { "true", "false" };
0998: terminateOnByte = new StringSpec(numTiles, numComponents,
0999: ModuleSpec.SPEC_TYPE_TILE_COMP, "false", strBoolean,
1000: this , values);
1001: }
1002:
1003: /** Gets <code>terminateOnByte</code> */
1004: public StringSpec getTerminateOnByte() {
1005: return terminateOnByte;
1006: }
1007:
1008: /** Sets <code>resetMQ</code> */
1009: public void setResetMQ(String values) {
1010: String[] strBoolean = { "true", "false" };
1011: resetMQ = new StringSpec(numTiles, numComponents,
1012: ModuleSpec.SPEC_TYPE_TILE_COMP, "false", strBoolean,
1013: this , values);
1014: }
1015:
1016: /** Gets <code>resetMQ</code> */
1017: public StringSpec getResetMQ() {
1018: return resetMQ;
1019: }
1020:
1021: /** Sets <code>bypass</code> */
1022: public void setBypass(String values) {
1023: String[] strBoolean = { "true", "false" };
1024: bypass = new StringSpec(numTiles, numComponents,
1025: ModuleSpec.SPEC_TYPE_TILE_COMP, "false", strBoolean,
1026: this , values);
1027: }
1028:
1029: /** Gets <code>bypass</code> */
1030: public StringSpec getBypass() {
1031: return bypass;
1032: }
1033:
1034: /** Sets <code>codeBlockSize</code> */
1035: public void setCodeBlockSize(String values) {
1036: codeBlockSize = new CBlkSizeSpec(numTiles, numComponents,
1037: ModuleSpec.SPEC_TYPE_TILE_COMP, this , values);
1038: }
1039:
1040: /** Gets <code>codeBlockSize</code> */
1041: public CBlkSizeSpec getCodeBlockSize() {
1042: return codeBlockSize;
1043: }
1044:
1045: /** Sets <code>precinctPartition</code> */
1046: public void setPrecinctPartition(String values) {
1047: String[] strBoolean = { "true", "false" };
1048: if (imgsrc != null)
1049: precinctPartition = new PrecinctSizeSpec(numTiles,
1050: numComponents, ModuleSpec.SPEC_TYPE_TILE_COMP,
1051: new RenderedImageSrc(imgsrc, this , null),
1052: decompositionLevel, this , values);
1053: else if (raster != null)
1054: precinctPartition = new PrecinctSizeSpec(numTiles,
1055: numComponents, ModuleSpec.SPEC_TYPE_TILE_COMP,
1056: new RenderedImageSrc(raster, this , null),
1057: decompositionLevel, this , values);
1058: }
1059:
1060: /** Gets <code>precinctPartition</code> */
1061: public PrecinctSizeSpec getPrecinctPartition() {
1062: return precinctPartition;
1063: }
1064:
1065: /** Sets <code>SOP</code> */
1066: public void setSOP(String values) {
1067: String[] strBoolean = { "true", "false" };
1068: SOP = new StringSpec(numTiles, numComponents,
1069: ModuleSpec.SPEC_TYPE_TILE_COMP, "false", strBoolean,
1070: this , values);
1071: }
1072:
1073: /** Gets <code>SOP</code> */
1074: public StringSpec getSOP() {
1075: return SOP;
1076: }
1077:
1078: /** Sets <code>EPH</code> */
1079: public void setEPH(String values) {
1080: String[] strBoolean = { "true", "false" };
1081: EPH = new StringSpec(numTiles, numComponents,
1082: ModuleSpec.SPEC_TYPE_TILE_COMP, "false", strBoolean,
1083: this , values);
1084: }
1085:
1086: /** Gets <code>EPH</code> */
1087: public StringSpec getEPH() {
1088: return EPH;
1089: }
1090:
1091: /** Sets <code>progressionName</code> */
1092: public void setProgressionName(String values) {
1093: progressionName = values;
1094: }
1095:
1096: /** Gets <code>progressionType</code> */
1097: public String getProgressionName() {
1098: return progressionName;
1099: }
1100:
1101: /** Sets <code>progressionType</code> */
1102: public void setProgressionType(LayersInfo lyrs, String values) {
1103: String[] strBoolean = { "true", "false" };
1104: progressionType = new ProgressionSpec(numTiles, numComponents,
1105: lyrs.getTotNumLayers(), decompositionLevel,
1106: ModuleSpec.SPEC_TYPE_TILE_COMP, this , values);
1107: }
1108:
1109: /** Gets <code>progressionType</code> */
1110: public ProgressionSpec getProgressionType() {
1111: return progressionType;
1112: }
1113:
1114: /** Sets the <code>startLevelROI</code> */
1115: public void setStartLevelROI(int value) {
1116: startLevelROI = value;
1117: }
1118:
1119: /** Gets <code>startLevel</code> */
1120: public int getStartLevelROI() {
1121: return startLevelROI;
1122: }
1123:
1124: /** Sets the <code>layers</code> */
1125: public void setLayers(String value) {
1126: layers = value;
1127: }
1128:
1129: /** Gets <code>layers</code> */
1130: public String getLayers() {
1131: return layers;
1132: }
1133:
1134: /** Sets <code>minX</code> */
1135: public void setMinX(int minX) {
1136: this .minX = minX;
1137: }
1138:
1139: /** Gets <code>minX</code> */
1140: public int getMinX() {
1141: return minX;
1142: }
1143:
1144: /** Sets <code>minY</code> */
1145: public void setMinY(int minY) {
1146: this .minY = minY;
1147: }
1148:
1149: /** Gets <code>minY</code> */
1150: public int getMinY() {
1151: return minY;
1152: }
1153:
1154: /** Gets the number of tiles */
1155: public int getNumTiles() {
1156: Rectangle sourceRegion = getSourceRegion();
1157: if (sourceRegion == null) {
1158: if (imgsrc != null)
1159: sourceRegion = new Rectangle(imgsrc.getMinX(), imgsrc
1160: .getMinY(), imgsrc.getWidth(), imgsrc
1161: .getHeight());
1162: else
1163: sourceRegion = raster.getBounds();
1164: } else {
1165: if (imgsrc != null)
1166: sourceRegion = sourceRegion.intersection(new Rectangle(
1167: imgsrc.getMinX(), imgsrc.getMinY(), imgsrc
1168: .getWidth(), imgsrc.getHeight()));
1169: else
1170: sourceRegion = sourceRegion.intersection(raster
1171: .getBounds());
1172: }
1173:
1174: int scaleX = getSourceXSubsampling();
1175: int scaleY = getSourceYSubsampling();
1176: int xOffset = getSubsamplingXOffset();
1177: int yOffset = getSubsamplingYOffset();
1178:
1179: int w = (sourceRegion.width - xOffset + scaleX - 1) / scaleX;
1180: int h = (sourceRegion.height - yOffset + scaleY - 1) / scaleY;
1181:
1182: minX = (sourceRegion.x + xOffset) / scaleX;
1183: minY = (sourceRegion.y + yOffset) / scaleY;
1184:
1185: numTiles = (int) ((Math.floor((minX + w + tileWidth - 1.0)
1186: / tileWidth) - Math.floor((double) minX / tileWidth)) * (Math
1187: .floor((minY + h + tileHeight - 1.0) / tileHeight) - Math
1188: .floor((double) minY / tileHeight)));
1189: tileGridXOffset += (minX - tileGridXOffset) / tileWidth
1190: * tileWidth;
1191: tileGridYOffset += (minY - tileGridYOffset) / tileHeight
1192: * tileHeight;
1193:
1194: return numTiles;
1195: }
1196:
1197: /** Gets the number of components */
1198: public int getNumComponents() {
1199: return numComponents;
1200: }
1201:
1202: /** Override the method setSourceBands in the super class. This method
1203: * should be called before any tile-specific parameter setting method
1204: * to be called.
1205: */
1206: public void setSourceBands(int[] bands) {
1207: super .setSourceBands(bands);
1208: if (bands != null) {
1209: numComponents = bands.length;
1210: setDefaults();
1211: }
1212: }
1213:
1214: /** Override the method setTiling in the super class. This method
1215: * should be called before any tile-specific parameter setting method
1216: * to be called.
1217: */
1218: public void setTiling(int tw, int th, int xOff, int yOff) {
1219: super .setTiling(tw, th, xOff, yOff);
1220: getNumTiles();
1221: setDefaults();
1222: }
1223:
1224: /** Override the method setSourceSubsampling in the super class. This
1225: * method should be called before any tile-specific parameter setting
1226: * method to be called.
1227: */
1228: public void setSourceSubsampling(int sx, int sy, int xOff, int yOff) {
1229: super.setSourceSubsampling(sx, sy, xOff, yOff);
1230: getNumTiles();
1231: setDefaults();
1232: }
1233: }
|