/* * CVS identifier: * * $Id: CBlkRateDistStats.java,v 1.11 2001/09/14 09:23:51 grosbois Exp $ * * Class: CBlkRateDistStats * * Description: The coded (compressed) code-block with * rate-distortion statistics. * * * * COPYRIGHT: * * This software module was originally developed by Raphaël Grosbois and * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research * Centre France S.A) in the course of development of the JPEG2000 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This * software module is an implementation of a part of the JPEG 2000 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio * Systems AB and Canon Research Centre France S.A (collectively JJ2000 * Partners) agree not to assert against ISO/IEC and users of the JPEG * 2000 Standard (Users) any of their rights under the copyright, not * including other intellectual property rights, for this software module * with respect to the usage by ISO/IEC and Users of this software module * or modifications thereof for use in hardware or software products * claiming conformance to the JPEG 2000 Standard. Those intending to use * this software module in hardware or software products are advised that * their use may infringe existing patents. The original developers of * this software module, JJ2000 Partners and ISO/IEC assume no liability * for use of this software module or modifications thereof. No license * or right to this software module is granted for non JPEG 2000 Standard * conforming products. JJ2000 Partners have full right to use this * software module for his/her own purpose, assign or donate this * software module to any third party and to inhibit third parties from * using this software module for non JPEG 2000 Standard conforming * products. This copyright notice must be included in all copies or * derivative works of this software module. * * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; using CSJ2K.j2k.wavelet.analysis; using CSJ2K.j2k.entropy; namespace CSJ2K.j2k.entropy.encoder { /// This class stores coded (compressed) code-blocks with their associated /// rate-distortion statistics. This object should always contain all the /// compressed data of the code-block. It is applicable to the encoder engine /// only. Some data of the coded-block is stored in the super class, see /// CodedCBlk. /// ///

The rate-distortion statistics (i.e. R-D slope) is stored for valid /// points only. The set of valid points is determined by the entropy coder /// engine itself. Normally they are selected so as to lye in a convex hull, /// which can be achived by using the 'selectConvexHull' method of this class, /// but some other strategies might be employed.

/// ///

The rate (in bytes) for each truncation point (valid or not) is stored /// in the 'truncRates' array. The rate of a truncation point is the total /// number of bytes in 'data' (see super class) that have to be decoded to /// reach the truncation point.

/// ///

The slope (reduction of distortion divided by the increase in rate) at /// each of the valid truncation points is stored in 'truncSlopes'.

/// ///

The index of each valid truncation point is stored in 'truncIdxs'. The /// index should be interpreted in the following way: a valid truncation point /// at position 'n' has the index 'truncIdxs[n]', the rate /// 'truncRates[truncIdxs[n]]' and the slope 'truncSlopes[n]'. The arrays /// 'truncIdxs' and 'truncRates' have at least 'nVldTrunc' elements. The /// 'truncRates' array has at least 'nTotTrunc' elements.

/// ///

In addition the 'isTermPass' array contains a flag for each truncation /// point (valid and non-valid ones) that tells if the pass is terminated or /// not. If this variable is null then it means that no pass is terminated, /// except the last one which always is.

/// ///

The compressed data is stored in the 'data' member variable of the super /// class.

/// ///
/// /// /// public class CBlkRateDistStats:CodedCBlk { /// The subband to which the code-block belongs public SubbandAn sb; /// The total number of truncation points public int nTotTrunc; /// The number of valid truncation points public int nVldTrunc; /// The rate (in bytes) for each truncation point (valid and non-valid /// ones) /// public int[] truncRates; /// The distortion for each truncation point (valid and non-valid ones) public double[] truncDists; /// The negative of the rate-distortion slope for each valid truncation /// point /// public float[] truncSlopes; /// The indices of the valid truncation points, in increasing order. public int[] truncIdxs; /// Array of flags indicating terminated passes (valid or non-valid /// truncation points). /// public bool[] isTermPass; /// The number of ROI coefficients in the code-block public int nROIcoeff = 0; /// Number of ROI coding passes public int nROIcp = 0; /// Creates a new CBlkRateDistStats object without allocating any space for /// 'truncRates', 'truncSlopes', 'truncDists' and 'truncIdxs' or 'data'. /// /// public CBlkRateDistStats() { } /// Creates a new CBlkRateDistStats object and initializes the valid /// truncation points, their rates and their slopes, from the 'rates' and /// 'dist' arrays. The 'rates', 'dist' and 'termp' arrays must contain the /// rate (in bytes), the reduction in distortion (from nothing coded) and /// the flag indicating if termination is used, respectively, for each /// truncation point. /// ///

The valid truncation points are selected by taking them as lying on /// a convex hull. This is done by calling the method /// selectConvexHull().

/// ///

Note that the arrays 'rates' and 'termp' are copied, not referenced, /// so they can be modified after a call to this constructor.

/// ///
/// The horizontal index of the code-block, within the subband. /// /// /// The vertical index of the code-block, within the subband. /// /// /// The number of skipped most significant bit-planes for /// this code-block. /// /// /// The compressed data. This array is referenced by this /// object so it should not be modified after. /// /// /// The rates (in bytes) for each truncation point in the /// compressed data. This array is modified by the method but no reference /// is kept to it. /// /// /// The reduction in distortion (with respect to no /// information coded) for each truncation point. This array is modified by /// the method but no reference is kept to it. /// /// /// An array of boolean flags indicating, for each pass, if a /// pass is terminated or not (true if terminated). If null then it is /// assumed that no pass is terminated except the last one which always is. /// /// /// The number of truncation points contained in 'rates', 'dist' /// and 'termp'. /// /// /// If false the convex hull is constructed as for lossy /// coding. If true it is constructed as for lossless coding, in which case /// it is ensured that all bit-planes are sent (i.e. the last truncation /// point is always included). /// /// public CBlkRateDistStats(int m, int n, int skipMSBP, byte[] data, int[] rates, double[] dists, bool[] termp, int np, bool inclast):base(m, n, skipMSBP, data) { selectConvexHull(rates, dists, termp, np, inclast); } /// Compute the rate-distorsion slopes and selects those that lie in a /// convex hull. It will compute the slopes, select the ones that form the /// convex hull and initialize the 'truncIdxs' and 'truncSlopes' arrays, as /// well as 'nVldTrunc', with the selected truncation points. It will also /// initialize 'truncRates' and 'isTermPass' arrays, as well as /// 'nTotTrunc', with all the truncation points (selected or not). /// ///

Note that the arrays 'rates' and 'termp' are copied, not /// referenced, so they can be modified after a call to this method.

/// ///
/// The rates (in bytes) for each truncation point in the /// compressed data. This array is modified by the method. /// /// /// The reduction in distortion (with respect to no /// information coded) for each truncation point. This array is modified by /// the method. /// /// /// An array of boolean flags indicating, for each pass, if a /// pass is terminated or not (true if terminated). If null then it is /// assumed that no pass is terminated except the last one which always is. /// /// /// The number of truncation points contained in 'rates', 'dist' /// and 'termp'. /// /// /// If false the convex hull is constructed as for lossy /// coding. If true it is constructed as for lossless coding, in which case /// it is ensured that all bit-planes are sent (i.e. the last truncation /// point is always included). /// /// public virtual void selectConvexHull(int[] rates, double[] dists, bool[] termp, int n, bool inclast) { int first_pnt; // The first point containing some coded data int p; // last selected point int k; // current point int i; // current valid point int npnt; // number of selected (i.e. valid) points int delta_rate; // Rate difference double delta_dist; // Distortion difference float k_slope; // R-D slope for the current point float p_slope; // R-D slope for the last selected point //int ll_rate; // Rate for "lossless" coding (i.e. all coded info) // Convention: when a negative value is stored in 'rates' it meas an // invalid point. The absolute value is always the rate for that point. // Look for first point with some coded info (rate not 0) first_pnt = 0; while (first_pnt < n && rates[first_pnt] <= 0) { first_pnt++; } // Select the valid points npnt = n - first_pnt; p_slope = 0f; // To keep compiler happy //UPGRADE_NOTE: Label 'ploop' was moved. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1014'" do { p = - 1; for (k = first_pnt; k < n; k++) { if (rates[k] < 0) { // Already invalidated point continue; } // Calculate decrease in distortion and rate if (p >= 0) { delta_rate = rates[k] - rates[p]; delta_dist = dists[k] - dists[p]; } else { // This is with respect to no info coded delta_rate = rates[k]; delta_dist = dists[k]; } // If exactly same distortion don't eliminate if the rates are // equal, otherwise it can lead to infinite slope in lossless // coding. if (delta_dist < 0f || (delta_dist == 0f && delta_rate > 0)) { // This point increases distortion => invalidate rates[k] = - rates[k]; npnt--; continue; // Goto next point } //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" k_slope = (float) (delta_dist / delta_rate); // Check that there is a decrease in distortion, slope is not // infinite (i.e. delta_dist is not 0) and slope is // decreasing. if (p >= 0 && (delta_rate <= 0 || k_slope >= p_slope)) { // Last point was not good rates[p] = - rates[p]; // Remove p from valid points npnt--; //UPGRADE_NOTE: Labeled continue statement was changed to a goto statement. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1015'" goto ploop; // Restart from the first one } else { p_slope = k_slope; p = k; } } // If we get to last point we are done break; //UPGRADE_NOTE: Label 'ploop' was moved. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1014'" ploop: ; } while (true); // We end the loop with the break statement // If in lossless mode make sure we don't eliminate any last // bit-planes from being sent. if (inclast && n > 0 && rates[n - 1] < 0) { rates[n - 1] = - rates[n - 1]; // This rate can never be equal to any previous selected rate, // given the selection algorithm above, so no problem arises of // infinite slopes. npnt++; } // Initialize the arrays of this object nTotTrunc = n; nVldTrunc = npnt; truncRates = new int[n]; truncDists = new double[n]; truncSlopes = new float[npnt]; truncIdxs = new int[npnt]; if (termp != null) { isTermPass = new bool[n]; Array.Copy(termp, 0, isTermPass, 0, n); } else { isTermPass = null; } Array.Copy(rates, 0, truncRates, 0, n); for (k = first_pnt, p = - 1, i = 0; k < n; k++) { if (rates[k] > 0) { // A valid point truncDists[k] = dists[k]; if (p < 0) { // Only arrives at first valid point //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" truncSlopes[i] = (float) (dists[k] / rates[k]); } else { //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" truncSlopes[i] = (float) ((dists[k] - dists[p]) / (rates[k] - rates[p])); } truncIdxs[i] = k; i++; p = k; } else { truncDists[k] = - 1; truncRates[k] = - truncRates[k]; } } } /// Returns the contents of the object in a string. This is used for /// debugging. /// /// /// A string with the contents of the object /// /// public override System.String ToString() { System.String str = base.ToString() + "\n nVldTrunc=" + nVldTrunc + ", nTotTrunc=" + nTotTrunc + ", num. ROI" + " coeff=" + nROIcoeff + ", num. ROI coding passes=" + nROIcp + ", sb=" + sb.sbandIdx; // str += "\n\ttruncRates:\n"; // for(int i=0; i