001: /*
002: * $RCSfile: LayersInfo.java,v $
003: * $Revision: 1.1 $
004: * $Date: 2005/02/11 05:02:08 $
005: * $State: Exp $
006: *
007: * Class: LayersInfo
008: *
009: * Description: Specification of a layer
010: *
011: *
012: *
013: * COPYRIGHT:
014: *
015: * This software module was originally developed by Raphaël Grosbois and
016: * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
017: * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
018: * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
019: * Centre France S.A) in the course of development of the JPEG2000
020: * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
021: * software module is an implementation of a part of the JPEG 2000
022: * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
023: * Systems AB and Canon Research Centre France S.A (collectively JJ2000
024: * Partners) agree not to assert against ISO/IEC and users of the JPEG
025: * 2000 Standard (Users) any of their rights under the copyright, not
026: * including other intellectual property rights, for this software module
027: * with respect to the usage by ISO/IEC and Users of this software module
028: * or modifications thereof for use in hardware or software products
029: * claiming conformance to the JPEG 2000 Standard. Those intending to use
030: * this software module in hardware or software products are advised that
031: * their use may infringe existing patents. The original developers of
032: * this software module, JJ2000 Partners and ISO/IEC assume no liability
033: * for use of this software module or modifications thereof. No license
034: * or right to this software module is granted for non JPEG 2000 Standard
035: * conforming products. JJ2000 Partners have full right to use this
036: * software module for his/her own purpose, assign or donate this
037: * software module to any third party and to inhibit third parties from
038: * using this software module for non JPEG 2000 Standard conforming
039: * products. This copyright notice must be included in all copies or
040: * derivative works of this software module.
041: *
042: * Copyright (c) 1999/2000 JJ2000 Partners.
043: *
044: *
045: *
046: */
047:
048: package jj2000.j2k.entropy.encoder;
049:
050: /**
051: * This class stores the specification of a layer distribution in the
052: * bit stream. The specification is made of optimization points and a number of
053: * extra layers to add between the optimization points. Each optimization
054: * point creates a layer which is optimized by the rate allocator to the
055: * specified target bitrate. The extra layers are added by the rate allocator
056: * between the optimized layers, with the difference that they are not
057: * optimized (i.e. they have no precise target bitrate).
058: *
059: * <P>The overall target bitrate for the bit stream is always added as the last
060: * optimization point without any extra layers after it. If there are some
061: * optimization points whose target bitrate is larger than the overall target
062: * bitrate, the overall target bitrate will still appear as the last
063: * optimization point, even though it does not follow the increasing target
064: * bitrate order of the other optimization points. The rate allocator is
065: * responsible for eliminating layers that have target bitrates larger than
066: * the overall target bitrate.
067: *
068: * <P>Optimization points can be added with the addOptPoint() method. It takes
069: * the target bitrate for the optimized layer and the number of extra layers
070: * to add after it.
071: *
072: * <P>Information about the total number of layers, total number of
073: * optimization points, target bitrates, etc. can be obtained with the other
074: * methods.
075: * */
076: public class LayersInfo {
077:
078: /** The initial size for the arrays: 10 */
079: private final static int SZ_INIT = 10;
080:
081: /** The size increment for the arrays */
082: private final static int SZ_INCR = 5;
083:
084: /** The total number of layers */
085: // Starts at 1: overall target bitrate is always an extra optimized layer
086: int totlyrs = 1;
087:
088: /** The overall target bitrate, for the whole bit stream */
089: float totbrate;
090:
091: /** The number of optimized layers, or optimization points, without
092: * counting the extra one coming from the overall target bitrate */
093: int nopt;
094:
095: /** The target bitrate to which specified layers should be optimized. */
096: float optbrate[] = new float[SZ_INIT];
097:
098: /** The number of extra layers to be added after an optimized layer. After
099: * the layer that is optimized to optbrate[i], extralyrs[i] extra layers
100: * should be added. These layers are allocated between the bitrate
101: * optbrate[i] and the next optimized bitrate optbrate[i+1] or, if it does
102: * not exist, the overall target bitrate. */
103: int extralyrs[] = new int[SZ_INIT];
104:
105: /**
106: * Creates a new LayersInfo object. The overall target bitrate 'brate' is
107: * always an extra optimization point, with no extra layers are after
108: * it. Note that any optimization points that are added with addOptPoint()
109: * are always added before the overall target bitrate.
110: *
111: * @param brate The overall target bitrate for the bit stream
112: *
113: *
114: * */
115: public LayersInfo(float brate) {
116: if (brate <= 0) {
117: throw new IllegalArgumentException(
118: "Overall target bitrate must "
119: + "be a positive number");
120: }
121: totbrate = brate;
122: }
123:
124: /**
125: * Returns the overall target bitrate for the entire bit stream.
126: *
127: * @return The overall target bitrate
128: *
129: *
130: * */
131: public float getTotBitrate() {
132: return totbrate;
133: }
134:
135: /**
136: * Returns the total number of layers, according to the layer
137: * specification of this object and the overall target bitrate.
138: *
139: * @return The total number of layers, according to the layer spec.
140: *
141: *
142: * */
143: public int getTotNumLayers() {
144: return totlyrs;
145: }
146:
147: /**
148: * Returns the number of layers to optimize, or optimization points, as
149: * specified by this object.
150: *
151: * @return The number of optimization points
152: *
153: *
154: * */
155: public int getNOptPoints() {
156: // overall target bitrate is counted as extra
157: return nopt + 1;
158: }
159:
160: /**
161: * Returns the target bitrate of the optmimization point 'n'.
162: *
163: * @param n The optimization point index (starts at 0).
164: *
165: * @return The target bitrate (in bpp) for the optimization point 'n'.
166: *
167: *
168: * */
169: public float getTargetBitrate(int n) {
170: // overall target bitrate is counted as extra
171: return (n < nopt) ? optbrate[n] : totbrate;
172: }
173:
174: /**
175: * Returns the number of extra layers to add after the optimization point
176: * 'n', but before optimization point 'n+1'. If there is no optimization
177: * point 'n+1' then they should be added before the overall target bitrate.
178: *
179: * @param n The optimization point index (starts at 0).
180: *
181: * @return The number of extra (unoptimized) layers to add after the
182: * optimization point 'n'
183: *
184: *
185: * */
186: public int getExtraLayers(int n) {
187: // overall target bitrate is counted as extra
188: return (n < nopt) ? extralyrs[n] : 0;
189: }
190:
191: /**
192: * Adds a new optimization point, with target bitrate 'brate' and with
193: * 'elyrs' (unoptimized) extra layers after it. The target bitrate 'brate'
194: * must be larger than the previous optimization point. The arguments are
195: * checked and IllegalArgumentException is thrown if they are not correct.
196: *
197: * @param brate The target bitrate for the optimized layer.
198: *
199: * @param elyrs The number of extra (unoptimized) layers to add after the
200: * optimized layer.
201: *
202: *
203: * */
204: public void addOptPoint(float brate, int elyrs) {
205: // Check validity of arguments
206: if (brate <= 0) {
207: throw new IllegalArgumentException(
208: "Target bitrate must be positive");
209: }
210: if (elyrs < 0) {
211: throw new IllegalArgumentException(
212: "The number of extra layers " + "must be 0 or more");
213: }
214: if (nopt > 0 && optbrate[nopt - 1] >= brate) {
215: throw new IllegalArgumentException(
216: "New optimization point must have "
217: + "a target bitrate higher than the "
218: + "preceding one");
219: }
220: // Check room for new optimization point
221: if (optbrate.length == nopt) { // Need more room
222: float tbr[] = optbrate;
223: int tel[] = extralyrs;
224: // both arrays always have same size
225: optbrate = new float[optbrate.length + SZ_INCR];
226: extralyrs = new int[extralyrs.length + SZ_INCR];
227: System.arraycopy(tbr, 0, optbrate, 0, nopt);
228: System.arraycopy(tel, 0, extralyrs, 0, nopt);
229: }
230: // Add new optimization point
231: optbrate[nopt] = brate;
232: extralyrs[nopt] = elyrs;
233: nopt++;
234: // Update total number of layers
235: totlyrs += 1 + elyrs;
236: }
237: }
|