All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jj2000.j2k.entropy.encoder.PostCompRateAllocator Maven / Gradle / Ivy

Go to download

JPEG2000 support for Java Advanced Imaging Image I/O Tools API core. This module is licensed under the [JJ2000 license](LICENSE.txt) and is therefore NOT compatible with the GPL 3 license. It should be compatible with the LGPL 2.1 license.

There is a newer version: 1.4.0
Show newest version
/*
 * $RCSfile: PostCompRateAllocator.java,v $
 * $Revision: 1.1 $
 * $Date: 2005/02/11 05:02:09 $
 * $State: Exp $
 *
 * Class:                   PostCompRateAllocator
 *
 * Description:             Generic interface for post-compression
 *                          rate allocator.
 *
 *
 *
 * 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.
 *  */
package jj2000.j2k.entropy.encoder;

import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;

import jj2000.j2k.codestream.ProgressionType;
import jj2000.j2k.codestream.writer.CodestreamWriter;
import jj2000.j2k.codestream.writer.HeaderEncoder;
import jj2000.j2k.image.ImgDataAdapter;

import com.github.jaiimageio.jpeg2000.impl.J2KImageWriteParamJava;
/**
 * This is the abstract class from which post-compression rate allocators
 * which generate layers should inherit. The source of data is a
 * 'CodedCBlkDataSrcEnc' which delivers entropy coded blocks with
 * rate-distortion statistics.
 *
 * 

The post compression rate allocator implementation should create the * layers, according to a rate allocation policy, and send the packets to a * CodestreamWriter. Since the rate allocator sends the packets to the bit * stream then it should output the packets to the bit stream in the order * imposed by the bit stream profiles. * * @see CodedCBlkDataSrcEnc * * @see jj2000.j2k.codestream.writer.CodestreamWriter * */ public abstract class PostCompRateAllocator extends ImgDataAdapter { /** The prefix for rate allocation options: 'A' */ public final static char OPT_PREFIX = 'A'; /** The list of parameters that is accepted for entropy coding. Options * for entropy coding start with 'R'. */ private final static String [][] pinfo = { { "Aptype", "[] res|layer|res-pos|"+ "pos-comp|comp-pos [res_start comp_start layer_end res_end "+ "comp_end "+ "prog] [[res_start comp_start ly_end res_end comp_end prog] ...] ["+ "[] ...]", "Specifies which type of progression should be used when "+ "generating "+ "the codestream. The 'res' value generates a resolution "+ "progressive codestream with the number of layers specified by "+ "'Alayers' option. The 'layer' value 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'.\n"+ "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." , null}, { "Alayers", " [+] [] [...]]", "Explicitly specifies the codestream layer formation parameters. "+ "The parameter specifies the bitrate to which the first "+ "layer should be optimized. The parameter, if present, "+ "specifies the number of extra layers that should be added for "+ "scalability. These extra layers are not optimized. "+ "Any extra and 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 parameter are "+ "approximately log-spaced between the other target bitrates. If "+ "several [+] constructs appear the "+ " 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.","0.015 +20 2.0 +10"} }; /** The source of entropy coded data */ protected CodedCBlkDataSrcEnc src; /** The source of entropy coded data */ protected J2KImageWriteParamJava wp; /** The number of layers. */ protected int numLayers; /** The bit-stream writer */ CodestreamWriter bsWriter; /** The header encoder */ HeaderEncoder headEnc; /** * Initializes the source of entropy coded data. * * @param src The source of entropy coded data. * * @param ln The number of layers to create * * @param pt The Progression type, as defined in 'ProgressionType'. * * @param bw The packet bit stream writer. * * @see ProgressionType * */ public PostCompRateAllocator(CodedCBlkDataSrcEnc src, int nl, CodestreamWriter bw, J2KImageWriteParamJava wp) { super(src); this.src = src; this.wp = wp; numLayers = nl; bsWriter = bw; } /** * Keep a reference to the header encoder. * * @param headEnc The header encoder * */ public void setHeaderEncoder(HeaderEncoder headEnc){ this.headEnc = headEnc; } /** * Initializes the rate allocation points, taking into account header * overhead and such. This method must be called after the header has been * simulated but before calling the runAndWrite() one. The header must be * rewritten after a call to this method since the number of layers may * change. * * @param oldSyntax Whether or not the old syntax is used. * * @see #runAndWrite * */ public abstract void initialize() throws IOException; /** * Runs the rate allocation algorithm and writes the data to the * bit stream. This must be called after the initialize() method. * * @see #initialize * */ public abstract void runAndWrite() throws IOException; /** * Returns the number of layers that are actually generated. * * @return The number of layers generated. * */ public int getNumLayers() { return numLayers; } /** * Returns the parameters that are used in this class and implementing * classes. It returns a 2D String array. Each of the 1D arrays is for a * different option, and they have 3 elements. The first element is the * option name, the second one is the synopsis, the third one is a long * description of what the parameter is and the fourth is its default * value. The synopsis or description may be 'null', in which case it is * assumed that there is no synopsis or description of the option, * respectively. Null may be returned if no options are supported. * * @return the options name, their synopsis and their explanation, * or null if no options are supported. * */ public static String[][] getParameterInfo() { return pinfo; } /** * Creates a PostCompRateAllocator object for the appropriate rate * allocation parameters in the parameter list 'pl', having 'src' as the * source of entropy coded data, 'rate' as the target bitrate and 'bw' as * the bit stream writer object. * * @param src The source of entropy coded data. * * @param pl The parameter lis (or options). * * @param rate The target bitrate for the rate allocation * * @param bw The bit stream writer object, where the bit stream data will * be written. * */ public static PostCompRateAllocator createInstance(CodedCBlkDataSrcEnc src, float rate, CodestreamWriter bw, J2KImageWriteParamJava wp){ String lyropt = wp.getLayers(); if (lyropt == null) { if(wp.getROIs().getSpecified() == null) { lyropt = "res"; } else { lyropt = "layer"; } } // Construct the layer specification from the Alayers option LayersInfo lyrs = parseAlayers(lyropt,rate); int nTiles = wp.getNumTiles(); int nComp = wp.getNumComponents(); int numLayers = lyrs.getTotNumLayers(); // Parse the Progression type wp.setProgressionType(lyrs, wp.getProgressionName()); return new EBCOTRateAllocator(src,lyrs,bw,wp); } /** * Convenience method that parses the 'Alayers' option. * * @param params The parameters of the 'Alayers' option * * @param rate The overall target bitrate * * @return The layer specification. * */ private static LayersInfo parseAlayers(String params, float rate) { LayersInfo lyrs; StreamTokenizer stok; boolean islayer,ratepending; float r; lyrs = new LayersInfo(rate); stok = new StreamTokenizer(new StringReader(params)); stok.eolIsSignificant(false); try { stok.nextToken(); } catch (IOException e) { throw new Error("An IOException has ocurred where it "+ "should never occur"); } ratepending = false; islayer = false; r = 0; // to keep compiler happy while (stok.ttype != stok.TT_EOF) { switch(stok.ttype) { case StreamTokenizer.TT_NUMBER: if (islayer) { // layer parameter try { lyrs.addOptPoint(r,(int)stok.nval); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Error in 'Alayers' "+ "option: "+e.getMessage()); } ratepending = false; islayer = false; } else { // rate parameter if (ratepending) { // Add pending rate parameter try { lyrs.addOptPoint(r,0); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Error in 'Alayers' "+ "option: "+ e.getMessage()); } } // Now store new rate parameter r = (float) stok.nval; ratepending = true; } break; case '+': if (!ratepending || islayer) { throw new IllegalArgumentException("Layer parameter without "+ "previous rate parameter "+ "in 'Alayers' option"); } islayer = true; // Next number is layer parameter break; case StreamTokenizer.TT_WORD: try { stok.nextToken(); } catch(IOException e) { throw new Error("An IOException has ocurred where it "+ "should never occur"); } if (stok.ttype != stok.TT_EOF) { throw new IllegalArgumentException("'sl' argument of "+ "'-Alayers' option must be "+ "used alone."); } break; default: throw new IllegalArgumentException("Error parsing 'Alayers' "+ "option"); } try { stok.nextToken(); } catch (IOException e) { throw new Error("An IOException has ocurred where it "+ "should never occur"); } } if (islayer) { throw new IllegalArgumentException("Error parsing 'Alayers' "+ "option"); } if (ratepending) { try { lyrs.addOptPoint(r,0); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Error in 'Alayers' "+ "option: "+ e.getMessage()); } } return lyrs; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy