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
049package jj2000.j2k.entropy.encoder;
050
051/**
052 * This class stores the specification of a layer distribution in the
053 * bit stream. The specification is made of optimization points and a number of
054 * extra layers to add between the optimization points. Each optimization
055 * point creates a layer which is optimized by the rate allocator to the
056 * specified target bitrate. The extra layers are added by the rate allocator
057 * between the optimized layers, with the difference that they are not
058 * optimized (i.e. they have no precise target bitrate).
059 *
060 * <P>The overall target bitrate for the bit stream is always added as the last
061 * optimization point without any extra layers after it. If there are some
062 * optimization points whose target bitrate is larger than the overall target
063 * bitrate, the overall target bitrate will still appear as the last
064 * optimization point, even though it does not follow the increasing target
065 * bitrate order of the other optimization points. The rate allocator is
066 * responsible for eliminating layers that have target bitrates larger than
067 * the overall target bitrate.
068 *
069 * <P>Optimization points can be added with the addOptPoint() method. It takes
070 * the target bitrate for the optimized layer and the number of extra layers
071 * to add after it.
072 *
073 * <P>Information about the total number of layers, total number of
074 * optimization points, target bitrates, etc. can be obtained with the other
075 * methods.
076 * */
077public class LayersInfo {
078
079    /** The initial size for the arrays: 10 */
080    private final static int SZ_INIT = 10;
081
082    /** The size increment for the arrays */
083    private final static int SZ_INCR = 5;
084
085    /** The total number of layers */
086    // Starts at 1: overall target bitrate is always an extra optimized layer
087    int totlyrs = 1;
088
089    /** The overall target bitrate, for the whole bit stream */
090    float totbrate;
091
092    /** The number of optimized layers, or optimization points, without
093     * counting the extra one coming from the overall target bitrate */
094    int nopt;
095
096    /** The target bitrate to which specified layers should be optimized. */
097    float optbrate[] = new float[SZ_INIT];
098
099    /** The number of extra layers to be added after an optimized layer. After
100     * the layer that is optimized to optbrate[i], extralyrs[i] extra layers
101     * should be added. These layers are allocated between the bitrate
102     * optbrate[i] and the next optimized bitrate optbrate[i+1] or, if it does
103     * not exist, the overall target bitrate. */
104    int extralyrs[] = new int[SZ_INIT];
105
106    /**
107     * Creates a new LayersInfo object. The overall target bitrate 'brate' is
108     * always an extra optimization point, with no extra layers are after
109     * it. Note that any optimization points that are added with addOptPoint()
110     * are always added before the overall target bitrate.
111     *
112     * @param brate The overall target bitrate for the bit stream
113     *
114     *
115     * */
116    public LayersInfo(float brate) {
117        if (brate <= 0) {
118            throw new IllegalArgumentException("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
208                IllegalArgumentException("Target bitrate must be positive");
209        }
210        if (elyrs < 0) {
211            throw new IllegalArgumentException("The number of extra layers "+
212                                               "must be 0 or more");
213        }
214        if (nopt > 0 && optbrate[nopt-1]>=brate) {
215            throw new
216                IllegalArgumentException("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}