2009-09-30 23:50:03 +00:00
/ *
* CVS identifier :
*
* $ Id : HeaderEncoder . java , v 1.43 2001 / 10 / 12 09 : 02 : 14 grosbois Exp $
*
* Class : HeaderEncoder
*
* Description : Write codestream headers .
*
*
*
* COPYRIGHT :
*
* This software module was originally developed by Rapha <EFBFBD> l Grosbois and
* Diego Santa Cruz ( Swiss Federal Institute of Technology - EPFL ) ; Joel
* Askel <EFBFBD> f ( Ericsson Radio Systems AB ) ; and Bertrand Berthelot , David
* Bouchard , F <EFBFBD> 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.quantization.quantizer ;
using CSJ2K.j2k.wavelet.analysis ;
using CSJ2K.j2k.entropy.encoder ;
using CSJ2K.j2k.quantization ;
using CSJ2K.j2k.image.input ;
using CSJ2K.j2k.roi.encoder ;
using CSJ2K.j2k.codestream ;
using CSJ2K.j2k.wavelet ;
using CSJ2K.j2k.encoder ;
using CSJ2K.j2k.entropy ;
using CSJ2K.j2k.image ;
using CSJ2K.j2k.util ;
using CSJ2K.j2k.io ;
using CSJ2K.j2k ;
namespace CSJ2K.j2k.codestream.writer
{
/// <summary> This class writes almost of the markers and marker segments in main header
/// and in tile-part headers. It is created by the run() method of the Encoder
/// instance.
///
/// <p>A marker segment includes a marker and eventually marker segment
/// parameters. It is designed by the three letter code of the marker
/// associated with the marker segment. JPEG 2000 part I defines 6 types of
/// markers:
/// <ul>
/// <li>Delimiting : SOC,SOT,SOD,EOC (written in FileCodestreamWriter).</li>
/// <li>Fixed information: SIZ.</li>
/// <li>Functional: COD,COC,RGN,QCD,QCC,POC.</li>
/// <li> In bit-stream: SOP,EPH.</li>
/// <li> Pointer: TLM,PLM,PLT,PPM,PPT.</li>
/// <li> Informational: CRG,COM.</li>
/// </ul></p>
///
/// <p>Main Header is written when Encoder instance calls encodeMainHeader
/// whereas tile-part headers are written when the EBCOTRateAllocator instance
/// calls encodeTilePartHeader.</p>
///
/// </summary>
/// <seealso cref="Encoder">
/// </seealso>
/// <seealso cref="Markers">
/// </seealso>
/// <seealso cref="EBCOTRateAllocator">
///
/// </seealso>
public class HeaderEncoder
{
/// <summary> 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.
///
/// </summary>
/// <returns> the options name, their synopsis and their explanation, or null
/// if no options are supported.
///
/// </returns>
public static System . String [ ] [ ] ParameterInfo
{
get
{
return pinfo ;
}
}
/// <summary> Returns the byte-buffer used to store the codestream header.
///
/// </summary>
/// <returns> A byte array countaining codestream header
///
/// </returns>
virtual protected internal byte [ ] Buffer
{
get
{
return baos . ToArray ( ) ;
}
}
/// <summary> Returns the length of the header.
///
/// </summary>
/// <returns> The length of the header in bytes
///
/// </returns>
virtual public int Length
{
get
{
return ( int ) hbuf . BaseStream . Length ;
}
}
/// <summary> Returns the number of bytes used in the codestream header's buffer.
///
/// </summary>
/// <returns> Header length in buffer (without any header overhead)
///
/// </returns>
virtual protected internal int BufferLength
{
get
{
return ( int ) baos . Length ;
}
}
/// <summary>The prefix for the header encoder options: 'H' </summary>
public const char OPT_PREFIX = 'H' ;
/// <summary>The list of parameters that are accepted for the header encoder
/// module. Options for this modules start with 'H'.
/// </summary>
//UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
private static readonly System . String [ ] [ ] pinfo = new System . String [ ] [ ] { new System . String [ ] { "Hjj2000_COM" , null , "Writes or not the JJ2000 COM marker in the " + "codestream" , "off" } , new System . String [ ] { "HCOM" , "<Comment 1>[#<Comment 2>[#<Comment3...>]]" , "Adds COM marker segments in the codestream. Comments must be " + "separated with '#' and are written into distinct maker segments." , null } } ;
/// <summary>Nominal range bit of the component defining default values in QCD for
/// main header
/// </summary>
private int defimgn ;
/// <summary>Nominal range bit of the component defining default values in QCD for
/// tile headers
/// </summary>
private int deftilenr ;
/// <summary>The number of components in the image </summary>
private int nComp ;
/// <summary>Whether or not to write the JJ2000 COM marker segment </summary>
private bool enJJ2KMarkSeg = true ;
/// <summary>Other COM marker segments specified in the command line </summary>
private System . String otherCOMMarkSeg = null ;
/// <summary>The ByteArrayOutputStream to store header data. This handler is kept
/// in order to use methods not accessible from a general
/// DataOutputStream. For the other methods, it's better to use variable
/// hbuf.
///
/// </summary>
/// <seealso cref="hbuf">
/// </seealso>
protected internal System . IO . MemoryStream baos ;
/// <summary>The DataOutputStream to store header data. This kind of object is
/// useful to write short, int, .... It's constructor takes baos as
/// parameter.
///
/// </summary>
/// <seealso cref="baos">
///
/// </seealso>
//UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'"
protected internal System . IO . BinaryWriter hbuf ;
/// <summary>The image data reader. Source of original data info </summary>
protected internal ImgData origSrc ;
/// <summary>An array specifying, for each component,if the data was signed or not
///
/// </summary>
protected internal bool [ ] isOrigSig ;
/// <summary>Reference to the rate allocator </summary>
protected internal PostCompRateAllocator ralloc ;
/// <summary>Reference to the DWT module </summary>
protected internal ForwardWT dwt ;
/// <summary>Reference to the tiler module </summary>
protected internal Tiler tiler ;
/// <summary>Reference to the ROI module </summary>
protected internal ROIScaler roiSc ;
/// <summary>The encoder specifications </summary>
protected internal EncoderSpecs encSpec ;
/// <summary> Initializes the header writer with the references to the coding chain.
///
/// </summary>
/// <param name="origsrc">The original image data (before any component mixing,
/// tiling, etc.)
///
/// </param>
/// <param name="isorigsig">An array specifying for each component if it was
/// originally signed or not.
///
/// </param>
/// <param name="dwt">The discrete wavelet transform module.
///
/// </param>
/// <param name="tiler">The tiler module.
///
/// </param>
/// <param name="encSpec">The encoder specifications
///
/// </param>
/// <param name="roiSc">The ROI scaler module.
///
/// </param>
/// <param name="ralloc">The post compression rate allocator.
///
/// </param>
/// <param name="pl">ParameterList instance.
///
/// </param>
public HeaderEncoder ( ImgData origsrc , bool [ ] isorigsig , ForwardWT dwt , Tiler tiler , EncoderSpecs encSpec , ROIScaler roiSc , PostCompRateAllocator ralloc , ParameterList pl )
{
pl . checkList ( OPT_PREFIX , CSJ2K . j2k . util . ParameterList . toNameArray ( pinfo ) ) ;
if ( origsrc . NumComps ! = isorigsig . Length )
{
throw new System . ArgumentException ( ) ;
}
this . origSrc = origsrc ;
this . isOrigSig = isorigsig ;
this . dwt = dwt ;
this . tiler = tiler ;
this . encSpec = encSpec ;
this . roiSc = roiSc ;
this . ralloc = ralloc ;
baos = new System . IO . MemoryStream ( ) ;
//UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'"
hbuf = new CSJ2K . Util . EndianBinaryWriter ( baos , true ) ;
nComp = origsrc . NumComps ;
enJJ2KMarkSeg = pl . getBooleanParameter ( "Hjj2000_COM" ) ;
otherCOMMarkSeg = pl . getParameter ( "HCOM" ) ;
}
/// <summary> Resets the contents of this HeaderEncoder to its initial state. It
/// erases all the data in the header buffer and reactualizes the
/// headerLength field of the bit stream writer.
///
/// </summary>
public virtual void reset ( )
{
//UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'"
// CONVERSION PROBLEM?
//baos.reset();
baos . SetLength ( 0 ) ;
//UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'"
hbuf = new CSJ2K . Util . EndianBinaryWriter ( baos , true ) ; //new System.IO.BinaryWriter(baos);
}
/// <summary> Writes the header to the specified BinaryDataOutput.
///
/// </summary>
/// <param name="out">Where to write the header.
///
/// </param>
public virtual void writeTo ( BinaryDataOutput out_Renamed )
{
int i , len ;
byte [ ] buf ;
buf = Buffer ;
len = Length ;
for ( i = 0 ; i < len ; i + + )
{
out_Renamed . writeByte ( buf [ i ] ) ;
}
}
/// <summary> Writes the header to the specified OutputStream.
///
/// </summary>
/// <param name="out">Where to write the header.
///
/// </param>
public virtual void writeTo ( System . IO . Stream out_Renamed )
{
out_Renamed . Write ( Buffer , 0 , BufferLength ) ;
}
/// <summary> Start Of Codestream marker (SOC) signalling the beginning of a
/// codestream.
///
/// </summary>
private void writeSOC ( )
{
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . SOC ) ;
}
/// <summary> Writes SIZ marker segment of the codestream header. It is a fixed
/// information marker segment containing informations about image and tile
/// sizes. It is required in the main header immediately after SOC marker
/// segment.
///
/// </summary>
private void writeSIZ ( )
{
int tmp ;
// SIZ marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . SIZ ) ;
// Lsiz (Marker length) corresponding to
// Lsiz(2 bytes)+Rsiz(2)+Xsiz(4)+Ysiz(4)+XOsiz(4)+YOsiz(4)+
// XTsiz(4)+YTsiz(4)+XTOsiz(4)+YTOsiz(4)+Csiz(2)+
// (Ssiz(1)+XRsiz(1)+YRsiz(1))*nComp
// markSegLen = 38 + 3*nComp;
int markSegLen = 38 + 3 * nComp ;
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Rsiz (codestream capabilities)
hbuf . Write ( ( System . Int16 ) 0 ) ; // JPEG 2000 - Part I
// Xsiz (original image width)
hbuf . Write ( tiler . ImgWidth + tiler . ImgULX ) ;
// Ysiz (original image height)
hbuf . Write ( tiler . ImgHeight + tiler . ImgULY ) ;
// XOsiz (horizontal offset from the origin of the reference
// grid to the left side of the image area)
hbuf . Write ( tiler . ImgULX ) ;
// YOsiz (vertical offset from the origin of the reference
// grid to the top side of the image area)
hbuf . Write ( tiler . ImgULY ) ;
// XTsiz (nominal tile width)
hbuf . Write ( tiler . NomTileWidth ) ;
// YTsiz (nominal tile height)
hbuf . Write ( tiler . NomTileHeight ) ;
Coord torig = tiler . getTilingOrigin ( null ) ;
// XTOsiz (Horizontal offset from the origin of the reference
// grid to the left side of the first tile)
hbuf . Write ( torig . x ) ;
// YTOsiz (Vertical offset from the origin of the reference
// grid to the top side of the first tile)
hbuf . Write ( torig . y ) ;
// Csiz (number of components)
hbuf . Write ( ( System . Int16 ) nComp ) ;
// Bit-depth and downsampling factors.
for ( int c = 0 ; c < nComp ; c + + )
{
// Loop on each component
// Ssiz bit-depth before mixing
tmp = origSrc . getNomRangeBits ( c ) - 1 ;
tmp | = ( ( isOrigSig [ c ] ? 1 : 0 ) < < CSJ2K . j2k . codestream . Markers . SSIZ_DEPTH_BITS ) ;
hbuf . Write ( ( System . Byte ) tmp ) ;
// XRsiz (component sub-sampling value x-wise)
hbuf . Write ( ( System . Byte ) tiler . getCompSubsX ( c ) ) ;
// YRsiz (component sub-sampling value y-wise)
hbuf . Write ( ( System . Byte ) tiler . getCompSubsY ( c ) ) ;
} // End loop on each component
}
/// <summary> Writes COD marker segment. COD is a functional marker segment
/// containing the code style default (coding style, decomposition,
/// layering) used for compressing all the components in an image.
///
/// <p>The values can be overriden for an individual component by a COC
/// marker in either the main or the tile header.</p>
///
/// </summary>
/// <param name="mh">Flag indicating whether this marker belongs to the main
/// header
///
/// </param>
/// <param name="tileIdx">Tile index if the marker belongs to a tile-part header
///
/// </param>
/// <seealso cref="writeCOC">
///
/// </seealso>
protected internal virtual void writeCOD ( bool mh , int tileIdx )
{
AnWTFilter [ ] [ ] filt ;
bool precinctPartitionUsed ;
int tmp ;
int mrl = 0 , a = 0 ;
int ppx = 0 , ppy = 0 ;
Progression [ ] prog ;
if ( mh )
{
mrl = ( ( System . Int32 ) encSpec . dls . getDefault ( ) ) ;
// get default precinct size
ppx = encSpec . pss . getPPX ( - 1 , - 1 , mrl ) ;
ppy = encSpec . pss . getPPY ( - 1 , - 1 , mrl ) ;
prog = ( Progression [ ] ) ( encSpec . pocs . getDefault ( ) ) ;
}
else
{
mrl = ( ( System . Int32 ) encSpec . dls . getTileDef ( tileIdx ) ) ;
// get precinct size for specified tile
ppx = encSpec . pss . getPPX ( tileIdx , - 1 , mrl ) ;
ppy = encSpec . pss . getPPY ( tileIdx , - 1 , mrl ) ;
prog = ( Progression [ ] ) ( encSpec . pocs . getTileDef ( tileIdx ) ) ;
}
if ( ppx ! = CSJ2K . j2k . codestream . Markers . PRECINCT_PARTITION_DEF_SIZE | | ppy ! = CSJ2K . j2k . codestream . Markers . PRECINCT_PARTITION_DEF_SIZE )
{
precinctPartitionUsed = true ;
}
else
{
precinctPartitionUsed = false ;
}
if ( precinctPartitionUsed )
{
// If precinct partition is used we add one byte per resolution
// level i.e. mrl+1 (+1 for resolution 0).
a = mrl + 1 ;
}
// Write COD marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . COD ) ;
// Lcod (marker segment length (in bytes)) Basic : Lcod(2
// bytes)+Scod(1)+SGcod(4)+SPcod(5+a) where:
// a=0 if no precinct partition is used
// a=mrl+1 if precinct partition used
int markSegLen = 12 + a ;
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Scod (coding style parameter)
tmp = 0 ;
if ( precinctPartitionUsed )
{
tmp = CSJ2K . j2k . codestream . Markers . SCOX_PRECINCT_PARTITION ;
}
// Are SOP markers used ?
if ( mh )
{
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
if ( ( ( System . String ) encSpec . sops . getDefault ( ) . ToString ( ) ) . ToUpper ( ) . Equals ( "on" . ToUpper ( ) ) )
{
tmp | = CSJ2K . j2k . codestream . Markers . SCOX_USE_SOP ;
}
}
else
{
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
if ( ( ( System . String ) encSpec . sops . getTileDef ( tileIdx ) . ToString ( ) ) . ToUpper ( ) . Equals ( "on" . ToUpper ( ) ) )
{
tmp | = CSJ2K . j2k . codestream . Markers . SCOX_USE_SOP ;
}
}
// Are EPH markers used ?
if ( mh )
{
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
if ( ( ( System . String ) encSpec . ephs . getDefault ( ) . ToString ( ) ) . ToUpper ( ) . Equals ( "on" . ToUpper ( ) ) )
{
tmp | = CSJ2K . j2k . codestream . Markers . SCOX_USE_EPH ;
}
}
else
{
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
if ( ( ( System . String ) encSpec . ephs . getTileDef ( tileIdx ) . ToString ( ) ) . ToUpper ( ) . Equals ( "on" . ToUpper ( ) ) )
{
tmp | = CSJ2K . j2k . codestream . Markers . SCOX_USE_EPH ;
}
}
if ( dwt . CbULX ! = 0 )
tmp | = CSJ2K . j2k . codestream . Markers . SCOX_HOR_CB_PART ;
if ( dwt . CbULY ! = 0 )
tmp | = CSJ2K . j2k . codestream . Markers . SCOX_VER_CB_PART ;
hbuf . Write ( ( System . Byte ) tmp ) ;
// SGcod
// Progression order
hbuf . Write ( ( System . Byte ) prog [ 0 ] . type ) ;
// Number of layers
hbuf . Write ( ( System . Int16 ) ralloc . NumLayers ) ;
// Multiple component transform
// CSsiz (Color transform)
System . String str = null ;
if ( mh )
{
str = ( ( System . String ) encSpec . cts . getDefault ( ) ) ;
}
else
{
str = ( ( System . String ) encSpec . cts . getTileDef ( tileIdx ) ) ;
}
if ( str . Equals ( "none" ) )
{
hbuf . Write ( ( System . Byte ) 0 ) ;
}
else
{
hbuf . Write ( ( System . Byte ) 1 ) ;
}
// SPcod
// Number of decomposition levels
hbuf . Write ( ( System . Byte ) mrl ) ;
// Code-block width and height
if ( mh )
{
// main header, get default values
tmp = encSpec . cblks . getCBlkWidth ( ModuleSpec . SPEC_DEF , - 1 , - 1 ) ;
hbuf . Write ( ( System . Byte ) ( MathUtil . log2 ( tmp ) - 2 ) ) ;
tmp = encSpec . cblks . getCBlkHeight ( ModuleSpec . SPEC_DEF , - 1 , - 1 ) ;
hbuf . Write ( ( System . Byte ) ( MathUtil . log2 ( tmp ) - 2 ) ) ;
}
else
{
// tile header, get tile default values
tmp = encSpec . cblks . getCBlkWidth ( ModuleSpec . SPEC_TILE_DEF , tileIdx , - 1 ) ;
hbuf . Write ( ( System . Byte ) ( MathUtil . log2 ( tmp ) - 2 ) ) ;
tmp = encSpec . cblks . getCBlkHeight ( ModuleSpec . SPEC_TILE_DEF , tileIdx , - 1 ) ;
hbuf . Write ( ( System . Byte ) ( MathUtil . log2 ( tmp ) - 2 ) ) ;
}
// Style of the code-block coding passes
tmp = 0 ;
if ( mh )
{
// Main header
// Selective arithmetic coding bypass ?
if ( ( ( System . String ) encSpec . bms . getDefault ( ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_BYPASS ;
}
// MQ reset after each coding pass ?
if ( ( ( System . String ) encSpec . mqrs . getDefault ( ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_RESET_MQ ;
}
// MQ termination after each arithmetically coded coding pass ?
if ( ( ( System . String ) encSpec . rts . getDefault ( ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_TERM_PASS ;
}
// Vertically stripe-causal context mode ?
if ( ( ( System . String ) encSpec . css . getDefault ( ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_VERT_STR_CAUSAL ;
}
// Predictable termination ?
if ( ( ( System . String ) encSpec . tts . getDefault ( ) ) . Equals ( "predict" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_PRED_TERM ;
}
// Error resilience segmentation symbol insertion ?
if ( ( ( System . String ) encSpec . sss . getDefault ( ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_SEG_SYMBOLS ;
}
}
else
{
// Tile header
// Selective arithmetic coding bypass ?
if ( ( ( System . String ) encSpec . bms . getTileDef ( tileIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_BYPASS ;
}
// MQ reset after each coding pass ?
if ( ( ( System . String ) encSpec . mqrs . getTileDef ( tileIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_RESET_MQ ;
}
// MQ termination after each arithmetically coded coding pass ?
if ( ( ( System . String ) encSpec . rts . getTileDef ( tileIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_TERM_PASS ;
}
// Vertically stripe-causal context mode ?
if ( ( ( System . String ) encSpec . css . getTileDef ( tileIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_VERT_STR_CAUSAL ;
}
// Predictable termination ?
if ( ( ( System . String ) encSpec . tts . getTileDef ( tileIdx ) ) . Equals ( "predict" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_PRED_TERM ;
}
// Error resilience segmentation symbol insertion ?
if ( ( ( System . String ) encSpec . sss . getTileDef ( tileIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_SEG_SYMBOLS ;
}
}
hbuf . Write ( ( System . Byte ) tmp ) ;
// Wavelet transform
// Wavelet Filter
if ( mh )
{
filt = ( ( AnWTFilter [ ] [ ] ) encSpec . wfs . getDefault ( ) ) ;
hbuf . Write ( ( System . Byte ) filt [ 0 ] [ 0 ] . FilterType ) ;
}
else
{
filt = ( ( AnWTFilter [ ] [ ] ) encSpec . wfs . getTileDef ( tileIdx ) ) ;
hbuf . Write ( ( System . Byte ) filt [ 0 ] [ 0 ] . FilterType ) ;
}
// Precinct partition
if ( precinctPartitionUsed )
{
// Write the precinct size for each resolution level + 1
// (resolution 0) if precinct partition is used.
2017-05-16 19:41:03 -05:00
System . Collections . Generic . List < System . Int32 > [ ] v = null ;
2009-09-30 23:50:03 +00:00
if ( mh )
{
2017-05-16 19:41:03 -05:00
v = ( System . Collections . Generic . List < System . Int32 > [ ] ) encSpec . pss . getDefault ( ) ;
2009-09-30 23:50:03 +00:00
}
else
{
2017-05-16 19:41:03 -05:00
v = ( System . Collections . Generic . List < System . Int32 > [ ] ) encSpec . pss . getTileDef ( tileIdx ) ;
2009-09-30 23:50:03 +00:00
}
for ( int r = mrl ; r > = 0 ; r - - )
{
if ( r > = v [ 1 ] . Count )
{
tmp = ( ( System . Int32 ) v [ 1 ] [ v [ 1 ] . Count - 1 ] ) ;
}
else
{
tmp = ( ( System . Int32 ) v [ 1 ] [ r ] ) ;
}
int yExp = ( MathUtil . log2 ( tmp ) < < 4 ) & 0x00F0 ;
if ( r > = v [ 0 ] . Count )
{
tmp = ( ( System . Int32 ) v [ 0 ] [ v [ 0 ] . Count - 1 ] ) ;
}
else
{
tmp = ( ( System . Int32 ) v [ 0 ] [ r ] ) ;
}
int xExp = MathUtil . log2 ( tmp ) & 0x000F ;
hbuf . Write ( ( System . Byte ) ( yExp | xExp ) ) ;
}
}
}
/// <summary> Writes COC marker segment . It is a functional marker containing the
/// coding style for one component (coding style, decomposition, layering).
///
/// <p>Its values overrides any value previously set in COD in the main
/// header or in the tile header.</p>
///
/// </summary>
/// <param name="mh">Flag indicating whether the main header is to be written.
///
/// </param>
/// <param name="tileIdx">Tile index.
///
/// </param>
/// <param name="compIdx">index of the component which need use of the COC marker
/// segment.
///
/// </param>
/// <seealso cref="writeCOD">
///
/// </seealso>
protected internal virtual void writeCOC ( bool mh , int tileIdx , int compIdx )
{
AnWTFilter [ ] [ ] filt ;
bool precinctPartitionUsed ;
int tmp ;
int mrl = 0 , a = 0 ;
int ppx = 0 , ppy = 0 ;
Progression [ ] prog ;
if ( mh )
{
mrl = ( ( System . Int32 ) encSpec . dls . getCompDef ( compIdx ) ) ;
// Get precinct size for specified component
ppx = encSpec . pss . getPPX ( - 1 , compIdx , mrl ) ;
ppy = encSpec . pss . getPPY ( - 1 , compIdx , mrl ) ;
prog = ( Progression [ ] ) ( encSpec . pocs . getCompDef ( compIdx ) ) ;
}
else
{
mrl = ( ( System . Int32 ) encSpec . dls . getTileCompVal ( tileIdx , compIdx ) ) ;
// Get precinct size for specified component/tile
ppx = encSpec . pss . getPPX ( tileIdx , compIdx , mrl ) ;
ppy = encSpec . pss . getPPY ( tileIdx , compIdx , mrl ) ;
prog = ( Progression [ ] ) ( encSpec . pocs . getTileCompVal ( tileIdx , compIdx ) ) ;
}
if ( ppx ! = CSJ2K . j2k . codestream . Markers . PRECINCT_PARTITION_DEF_SIZE | | ppy ! = CSJ2K . j2k . codestream . Markers . PRECINCT_PARTITION_DEF_SIZE )
{
precinctPartitionUsed = true ;
}
else
{
precinctPartitionUsed = false ;
}
if ( precinctPartitionUsed )
{
// If precinct partition is used we add one byte per resolution
// level i.e. mrl+1 (+1 for resolution 0).
a = mrl + 1 ;
}
// COC marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . COC ) ;
// Lcoc (marker segment length (in bytes))
// Basic: Lcoc(2 bytes)+Scoc(1)+ Ccoc(1 or 2)+SPcod(5+a)
int markSegLen = 8 + ( ( nComp < 257 ) ? 1 : 2 ) + a ;
// Rounded to the nearest even value greater or equals
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Ccoc
if ( nComp < 257 )
{
hbuf . Write ( ( System . Byte ) compIdx ) ;
}
else
{
hbuf . Write ( ( System . Int16 ) compIdx ) ;
}
// Scod (coding style parameter)
tmp = 0 ;
if ( precinctPartitionUsed )
{
tmp = CSJ2K . j2k . codestream . Markers . SCOX_PRECINCT_PARTITION ;
}
hbuf . Write ( ( System . Byte ) tmp ) ;
// SPcoc
// Number of decomposition levels
hbuf . Write ( ( System . Byte ) mrl ) ;
// Code-block width and height
if ( mh )
{
// main header, get component default values
tmp = encSpec . cblks . getCBlkWidth ( ModuleSpec . SPEC_COMP_DEF , - 1 , compIdx ) ;
hbuf . Write ( ( System . Byte ) ( MathUtil . log2 ( tmp ) - 2 ) ) ;
tmp = encSpec . cblks . getCBlkHeight ( ModuleSpec . SPEC_COMP_DEF , - 1 , compIdx ) ;
hbuf . Write ( ( System . Byte ) ( MathUtil . log2 ( tmp ) - 2 ) ) ;
}
else
{
// tile header, get tile component values
tmp = encSpec . cblks . getCBlkWidth ( ModuleSpec . SPEC_TILE_COMP , tileIdx , compIdx ) ;
hbuf . Write ( ( System . Byte ) ( MathUtil . log2 ( tmp ) - 2 ) ) ;
tmp = encSpec . cblks . getCBlkHeight ( ModuleSpec . SPEC_TILE_COMP , tileIdx , compIdx ) ;
hbuf . Write ( ( System . Byte ) ( MathUtil . log2 ( tmp ) - 2 ) ) ;
}
// Entropy coding mode options
tmp = 0 ;
if ( mh )
{
// Main header
// Lazy coding mode ?
if ( ( ( System . String ) encSpec . bms . getCompDef ( compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_BYPASS ;
}
// MQ reset after each coding pass ?
if ( ( ( System . String ) encSpec . mqrs . getCompDef ( compIdx ) ) . ToUpper ( ) . Equals ( "on" . ToUpper ( ) ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_RESET_MQ ;
}
// MQ termination after each arithmetically coded coding pass ?
if ( ( ( System . String ) encSpec . rts . getCompDef ( compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_TERM_PASS ;
}
// Vertically stripe-causal context mode ?
if ( ( ( System . String ) encSpec . css . getCompDef ( compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_VERT_STR_CAUSAL ;
}
// Predictable termination ?
if ( ( ( System . String ) encSpec . tts . getCompDef ( compIdx ) ) . Equals ( "predict" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_PRED_TERM ;
}
// Error resilience segmentation symbol insertion ?
if ( ( ( System . String ) encSpec . sss . getCompDef ( compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_SEG_SYMBOLS ;
}
}
else
{
// Tile Header
if ( ( ( System . String ) encSpec . bms . getTileCompVal ( tileIdx , compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_BYPASS ;
}
// MQ reset after each coding pass ?
if ( ( ( System . String ) encSpec . mqrs . getTileCompVal ( tileIdx , compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_RESET_MQ ;
}
// MQ termination after each arithmetically coded coding pass ?
if ( ( ( System . String ) encSpec . rts . getTileCompVal ( tileIdx , compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_TERM_PASS ;
}
// Vertically stripe-causal context mode ?
if ( ( ( System . String ) encSpec . css . getTileCompVal ( tileIdx , compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_VERT_STR_CAUSAL ;
}
// Predictable termination ?
if ( ( ( System . String ) encSpec . tts . getTileCompVal ( tileIdx , compIdx ) ) . Equals ( "predict" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_PRED_TERM ;
}
// Error resilience segmentation symbol insertion ?
if ( ( ( System . String ) encSpec . sss . getTileCompVal ( tileIdx , compIdx ) ) . Equals ( "on" ) )
{
tmp | = CSJ2K . j2k . entropy . StdEntropyCoderOptions . OPT_SEG_SYMBOLS ;
}
}
hbuf . Write ( ( System . Byte ) tmp ) ;
// Wavelet transform
// Wavelet Filter
if ( mh )
{
filt = ( ( AnWTFilter [ ] [ ] ) encSpec . wfs . getCompDef ( compIdx ) ) ;
hbuf . Write ( ( System . Byte ) filt [ 0 ] [ 0 ] . FilterType ) ;
}
else
{
filt = ( ( AnWTFilter [ ] [ ] ) encSpec . wfs . getTileCompVal ( tileIdx , compIdx ) ) ;
hbuf . Write ( ( System . Byte ) filt [ 0 ] [ 0 ] . FilterType ) ;
}
// Precinct partition
if ( precinctPartitionUsed )
{
// Write the precinct size for each resolution level + 1
// (resolution 0) if precinct partition is used.
2017-05-16 19:41:03 -05:00
System . Collections . Generic . List < System . Int32 > [ ] v = null ;
2009-09-30 23:50:03 +00:00
if ( mh )
{
2017-05-16 19:41:03 -05:00
v = ( System . Collections . Generic . List < System . Int32 > [ ] ) encSpec . pss . getCompDef ( compIdx ) ;
2009-09-30 23:50:03 +00:00
}
else
{
2017-05-16 19:41:03 -05:00
v = ( System . Collections . Generic . List < System . Int32 > [ ] ) encSpec . pss . getTileCompVal ( tileIdx , compIdx ) ;
2009-09-30 23:50:03 +00:00
}
for ( int r = mrl ; r > = 0 ; r - - )
{
if ( r > = v [ 1 ] . Count )
{
tmp = ( ( System . Int32 ) v [ 1 ] [ v [ 1 ] . Count - 1 ] ) ;
}
else
{
tmp = ( ( System . Int32 ) v [ 1 ] [ r ] ) ;
}
int yExp = ( MathUtil . log2 ( tmp ) < < 4 ) & 0x00F0 ;
if ( r > = v [ 0 ] . Count )
{
tmp = ( ( System . Int32 ) v [ 0 ] [ v [ 0 ] . Count - 1 ] ) ;
}
else
{
tmp = ( ( System . Int32 ) v [ 0 ] [ r ] ) ;
}
int xExp = MathUtil . log2 ( tmp ) & 0x000F ;
hbuf . Write ( ( System . Byte ) ( yExp | xExp ) ) ;
}
}
}
/// <summary> Writes QCD marker segment in main header. QCD is a functional marker
/// segment countaining the quantization default used for compressing all
/// the components in an image. The values can be overriden for an
/// individual component by a QCC marker in either the main or the tile
/// header.
///
/// </summary>
protected internal virtual void writeMainQCD ( )
{
int mrl ;
int qstyle ;
float step ;
System . String qType = ( System . String ) encSpec . qts . getDefault ( ) ;
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
float baseStep = ( float ) ( ( System . Single ) encSpec . qsss . getDefault ( ) ) ;
int gb = ( ( System . Int32 ) encSpec . gbs . getDefault ( ) ) ;
bool isDerived = qType . Equals ( "derived" ) ;
bool isReversible = qType . Equals ( "reversible" ) ;
mrl = ( ( System . Int32 ) encSpec . dls . getDefault ( ) ) ;
int nt = dwt . getNumTiles ( ) ;
int nc = dwt . NumComps ;
int tmpI ;
int [ ] tcIdx = new int [ 2 ] ;
System . String tmpStr ;
bool notFound = true ;
for ( int t = 0 ; t < nt & & notFound ; t + + )
{
for ( int c = 0 ; c < nc & & notFound ; c + + )
{
tmpI = ( ( System . Int32 ) encSpec . dls . getTileCompVal ( t , c ) ) ;
tmpStr = ( ( System . String ) encSpec . qts . getTileCompVal ( t , c ) ) ;
if ( tmpI = = mrl & & tmpStr . Equals ( qType ) )
{
tcIdx [ 0 ] = t ; tcIdx [ 1 ] = c ;
notFound = false ;
}
}
}
if ( notFound )
{
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCD marker segment. " + "You have found a JJ2000 bug." ) ;
2009-09-30 23:50:03 +00:00
}
SubbandAn sb , csb , sbRoot = dwt . getAnSubbandTree ( tcIdx [ 0 ] , tcIdx [ 1 ] ) ;
defimgn = dwt . getNomRangeBits ( tcIdx [ 1 ] ) ;
int nqcd ; // Number of quantization step-size to transmit
// Get the quantization style
qstyle = ( isReversible ) ? CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION : ( ( isDerived ) ? CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED : CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED ) ;
// QCD marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . QCD ) ;
// Compute the number of steps to send
switch ( qstyle )
{
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED :
nqcd = 1 ; // Just the LL value
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION :
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED :
// One value per subband
nqcd = 0 ;
sb = sbRoot ;
// Get the subband at first resolution level
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Count total number of subbands
for ( int j = 0 ; j < = mrl ; j + + )
{
csb = sb ;
while ( csb ! = null )
{
nqcd + + ;
csb = ( SubbandAn ) csb . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
default :
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Internal JJ2000 error" ) ;
2009-09-30 23:50:03 +00:00
}
// Lqcd (marker segment length (in bytes))
// Lqcd(2 bytes)+Sqcd(1)+ SPqcd (2*Nqcd)
int markSegLen = 3 + ( ( isReversible ) ? nqcd : 2 * nqcd ) ;
// Rounded to the nearest even value greater or equals
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Sqcd
hbuf . Write ( ( System . Byte ) ( qstyle + ( gb < < CSJ2K . j2k . codestream . Markers . SQCX_GB_SHIFT ) ) ) ;
// SPqcd
switch ( qstyle )
{
case CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION :
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Output one exponent per subband
for ( int j = 0 ; j < = mrl ; j + + )
{
csb = sb ;
while ( csb ! = null )
{
int tmp = ( defimgn + csb . anGainExp ) ;
hbuf . Write ( ( System . Byte ) ( tmp < < CSJ2K . j2k . codestream . Markers . SQCX_EXP_SHIFT ) ) ;
csb = ( SubbandAn ) csb . nextSubband ( ) ;
// Go up one resolution level
}
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED :
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / ( 1 < < sb . level ) ;
// Write exponent-mantissa, 16 bits
hbuf . Write ( ( System . Int16 ) StdQuantizer . convertToExpMantissa ( step ) ) ;
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED :
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Output one step per subband
for ( int j = 0 ; j < = mrl ; j + + )
{
csb = sb ;
while ( csb ! = null )
{
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / ( csb . l2Norm * ( 1 < < csb . anGainExp ) ) ;
// Write exponent-mantissa, 16 bits
hbuf . Write ( ( System . Int16 ) StdQuantizer . convertToExpMantissa ( step ) ) ;
csb = ( SubbandAn ) csb . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
default :
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Internal JJ2000 error" ) ;
2009-09-30 23:50:03 +00:00
}
}
/// <summary> Writes QCC marker segment in main header. It is a functional marker
/// segment countaining the quantization used for compressing the specified
/// component in an image. The values override for the specified component
/// what was defined by a QCC marker in either the main or the tile header.
///
/// </summary>
/// <param name="compIdx">Index of the component which needs QCC marker segment.
///
/// </param>
protected internal virtual void writeMainQCC ( int compIdx )
{
int mrl ;
int qstyle ;
int tIdx = 0 ;
float step ;
SubbandAn sb , sb2 ;
SubbandAn sbRoot ;
int imgnr = dwt . getNomRangeBits ( compIdx ) ;
System . String qType = ( System . String ) encSpec . qts . getCompDef ( compIdx ) ;
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
float baseStep = ( float ) ( ( System . Single ) encSpec . qsss . getCompDef ( compIdx ) ) ;
int gb = ( ( System . Int32 ) encSpec . gbs . getCompDef ( compIdx ) ) ;
bool isReversible = qType . Equals ( "reversible" ) ;
bool isDerived = qType . Equals ( "derived" ) ;
mrl = ( ( System . Int32 ) encSpec . dls . getCompDef ( compIdx ) ) ;
int nt = dwt . getNumTiles ( ) ;
int nc = dwt . NumComps ;
int tmpI ;
System . String tmpStr ;
bool notFound = true ;
for ( int t = 0 ; t < nt & & notFound ; t + + )
{
for ( int c = 0 ; c < nc & & notFound ; c + + )
{
tmpI = ( ( System . Int32 ) encSpec . dls . getTileCompVal ( t , c ) ) ;
tmpStr = ( ( System . String ) encSpec . qts . getTileCompVal ( t , c ) ) ;
if ( tmpI = = mrl & & tmpStr . Equals ( qType ) )
{
tIdx = t ;
notFound = false ;
}
}
}
if ( notFound )
{
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCC (c=" + compIdx + ") marker segment. " + "You have found a JJ2000 bug." ) ;
2009-09-30 23:50:03 +00:00
}
sbRoot = dwt . getAnSubbandTree ( tIdx , compIdx ) ;
int nqcc ; // Number of quantization step-size to transmit
// Get the quantization style
if ( isReversible )
{
qstyle = CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION ;
}
else if ( isDerived )
{
qstyle = CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED ;
}
else
{
qstyle = CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED ;
}
// QCC marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . QCC ) ;
// Compute the number of steps to send
switch ( qstyle )
{
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED :
nqcc = 1 ; // Just the LL value
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION :
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED :
// One value per subband
nqcc = 0 ;
sb = sbRoot ;
mrl = sb . resLvl ;
// Get the subband at first resolution level
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Find root element for LL subband
while ( sb . resLvl ! = 0 )
{
sb = sb . subb_LL ;
}
// Count total number of subbands
for ( int j = 0 ; j < = mrl ; j + + )
{
sb2 = sb ;
while ( sb2 ! = null )
{
nqcc + + ;
sb2 = ( SubbandAn ) sb2 . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
default :
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Internal JJ2000 error" ) ;
2009-09-30 23:50:03 +00:00
}
// Lqcc (marker segment length (in bytes))
// Lqcc(2 bytes)+Cqcc(1 or 2)+Sqcc(1)+ SPqcc (2*Nqcc)
int markSegLen = 3 + ( ( nComp < 257 ) ? 1 : 2 ) + ( ( isReversible ) ? nqcc : 2 * nqcc ) ;
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Cqcc
if ( nComp < 257 )
{
hbuf . Write ( ( System . Byte ) compIdx ) ;
}
else
{
hbuf . Write ( ( System . Int16 ) compIdx ) ;
}
// Sqcc (quantization style)
hbuf . Write ( ( System . Byte ) ( qstyle + ( gb < < CSJ2K . j2k . codestream . Markers . SQCX_GB_SHIFT ) ) ) ;
// SPqcc
switch ( qstyle )
{
case CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION :
// Get resolution level 0 subband
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Output one exponent per subband
for ( int j = 0 ; j < = mrl ; j + + )
{
sb2 = sb ;
while ( sb2 ! = null )
{
int tmp = ( imgnr + sb2 . anGainExp ) ;
hbuf . Write ( ( System . Byte ) ( tmp < < CSJ2K . j2k . codestream . Markers . SQCX_EXP_SHIFT ) ) ;
sb2 = ( SubbandAn ) sb2 . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED :
// Get resolution level 0 subband
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / ( 1 < < sb . level ) ;
// Write exponent-mantissa, 16 bits
hbuf . Write ( ( System . Int16 ) StdQuantizer . convertToExpMantissa ( step ) ) ;
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED :
// Get resolution level 0 subband
sb = sbRoot ;
mrl = sb . resLvl ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
for ( int j = 0 ; j < = mrl ; j + + )
{
sb2 = sb ;
while ( sb2 ! = null )
{
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / ( sb2 . l2Norm * ( 1 < < sb2 . anGainExp ) ) ;
// Write exponent-mantissa, 16 bits
hbuf . Write ( ( System . Int16 ) StdQuantizer . convertToExpMantissa ( step ) ) ;
sb2 = ( SubbandAn ) sb2 . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
default :
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Internal JJ2000 error" ) ;
2009-09-30 23:50:03 +00:00
}
}
/// <summary> Writes QCD marker segment in tile header. QCD is a functional marker
/// segment countaining the quantization default used for compressing all
/// the components in an image. The values can be overriden for an
/// individual component by a QCC marker in either the main or the tile
/// header.
///
/// </summary>
/// <param name="tIdx">Tile index
///
/// </param>
protected internal virtual void writeTileQCD ( int tIdx )
{
int mrl ;
int qstyle ;
float step ;
SubbandAn sb , csb , sbRoot ;
System . String qType = ( System . String ) encSpec . qts . getTileDef ( tIdx ) ;
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
float baseStep = ( float ) ( ( System . Single ) encSpec . qsss . getTileDef ( tIdx ) ) ;
mrl = ( ( System . Int32 ) encSpec . dls . getTileDef ( tIdx ) ) ;
int nc = dwt . NumComps ;
int tmpI ;
System . String tmpStr ;
bool notFound = true ;
int compIdx = 0 ;
for ( int c = 0 ; c < nc & & notFound ; c + + )
{
tmpI = ( ( System . Int32 ) encSpec . dls . getTileCompVal ( tIdx , c ) ) ;
tmpStr = ( ( System . String ) encSpec . qts . getTileCompVal ( tIdx , c ) ) ;
if ( tmpI = = mrl & & tmpStr . Equals ( qType ) )
{
compIdx = c ;
notFound = false ;
}
}
if ( notFound )
{
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Default representative for quantization type " + " and number of decomposition levels not found " + " in tile QCD (t=" + tIdx + ") marker segment. " + "You have found a JJ2000 bug." ) ;
2009-09-30 23:50:03 +00:00
}
sbRoot = dwt . getAnSubbandTree ( tIdx , compIdx ) ;
deftilenr = dwt . getNomRangeBits ( compIdx ) ;
int gb = ( ( System . Int32 ) encSpec . gbs . getTileDef ( tIdx ) ) ;
bool isDerived = qType . Equals ( "derived" ) ;
bool isReversible = qType . Equals ( "reversible" ) ;
int nqcd ; // Number of quantization step-size to transmit
// Get the quantization style
qstyle = ( isReversible ) ? CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION : ( ( isDerived ) ? CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED : CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED ) ;
// QCD marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . QCD ) ;
// Compute the number of steps to send
switch ( qstyle )
{
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED :
nqcd = 1 ; // Just the LL value
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION :
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED :
// One value per subband
nqcd = 0 ;
sb = sbRoot ;
// Get the subband at first resolution level
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Count total number of subbands
for ( int j = 0 ; j < = mrl ; j + + )
{
csb = sb ;
while ( csb ! = null )
{
nqcd + + ;
csb = ( SubbandAn ) csb . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
default :
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Internal JJ2000 error" ) ;
2009-09-30 23:50:03 +00:00
}
// Lqcd (marker segment length (in bytes))
// Lqcd(2 bytes)+Sqcd(1)+ SPqcd (2*Nqcd)
int markSegLen = 3 + ( ( isReversible ) ? nqcd : 2 * nqcd ) ;
// Rounded to the nearest even value greater or equals
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Sqcd
hbuf . Write ( ( System . Byte ) ( qstyle + ( gb < < CSJ2K . j2k . codestream . Markers . SQCX_GB_SHIFT ) ) ) ;
// SPqcd
switch ( qstyle )
{
case CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION :
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Output one exponent per subband
for ( int j = 0 ; j < = mrl ; j + + )
{
csb = sb ;
while ( csb ! = null )
{
int tmp = ( deftilenr + csb . anGainExp ) ;
hbuf . Write ( ( System . Byte ) ( tmp < < CSJ2K . j2k . codestream . Markers . SQCX_EXP_SHIFT ) ) ;
csb = ( SubbandAn ) csb . nextSubband ( ) ;
// Go up one resolution level
}
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED :
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / ( 1 < < sb . level ) ;
// Write exponent-mantissa, 16 bits
hbuf . Write ( ( System . Int16 ) StdQuantizer . convertToExpMantissa ( step ) ) ;
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED :
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Output one step per subband
for ( int j = 0 ; j < = mrl ; j + + )
{
csb = sb ;
while ( csb ! = null )
{
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / ( csb . l2Norm * ( 1 < < csb . anGainExp ) ) ;
// Write exponent-mantissa, 16 bits
hbuf . Write ( ( System . Int16 ) StdQuantizer . convertToExpMantissa ( step ) ) ;
csb = ( SubbandAn ) csb . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
default :
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Internal JJ2000 error" ) ;
2009-09-30 23:50:03 +00:00
}
}
/// <summary> Writes QCC marker segment in tile header. It is a functional marker
/// segment countaining the quantization used for compressing the specified
/// component in an image. The values override for the specified component
/// what was defined by a QCC marker in either the main or the tile header.
///
/// </summary>
/// <param name="t">Tile index
///
/// </param>
/// <param name="compIdx">Index of the component which needs QCC marker segment.
///
/// </param>
protected internal virtual void writeTileQCC ( int t , int compIdx )
{
int mrl ;
int qstyle ;
float step ;
SubbandAn sb , sb2 ;
int nqcc ; // Number of quantization step-size to transmit
SubbandAn sbRoot = dwt . getAnSubbandTree ( t , compIdx ) ;
int imgnr = dwt . getNomRangeBits ( compIdx ) ;
System . String qType = ( System . String ) encSpec . qts . getTileCompVal ( t , compIdx ) ;
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
float baseStep = ( float ) ( ( System . Single ) encSpec . qsss . getTileCompVal ( t , compIdx ) ) ;
int gb = ( ( System . Int32 ) encSpec . gbs . getTileCompVal ( t , compIdx ) ) ;
bool isReversible = qType . Equals ( "reversible" ) ;
bool isDerived = qType . Equals ( "derived" ) ;
mrl = ( ( System . Int32 ) encSpec . dls . getTileCompVal ( t , compIdx ) ) ;
// Get the quantization style
if ( isReversible )
{
qstyle = CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION ;
}
else if ( isDerived )
{
qstyle = CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED ;
}
else
{
qstyle = CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED ;
}
// QCC marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . QCC ) ;
// Compute the number of steps to send
switch ( qstyle )
{
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED :
nqcc = 1 ; // Just the LL value
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION :
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED :
// One value per subband
nqcc = 0 ;
sb = sbRoot ;
mrl = sb . resLvl ;
// Get the subband at first resolution level
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Find root element for LL subband
while ( sb . resLvl ! = 0 )
{
sb = sb . subb_LL ;
}
// Count total number of subbands
for ( int j = 0 ; j < = mrl ; j + + )
{
sb2 = sb ;
while ( sb2 ! = null )
{
nqcc + + ;
sb2 = ( SubbandAn ) sb2 . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
default :
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Internal JJ2000 error" ) ;
2009-09-30 23:50:03 +00:00
}
// Lqcc (marker segment length (in bytes))
// Lqcc(2 bytes)+Cqcc(1 or 2)+Sqcc(1)+ SPqcc (2*Nqcc)
int markSegLen = 3 + ( ( nComp < 257 ) ? 1 : 2 ) + ( ( isReversible ) ? nqcc : 2 * nqcc ) ;
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Cqcc
if ( nComp < 257 )
{
hbuf . Write ( ( System . Byte ) compIdx ) ;
}
else
{
hbuf . Write ( ( System . Int16 ) compIdx ) ;
}
// Sqcc (quantization style)
hbuf . Write ( ( System . Byte ) ( qstyle + ( gb < < CSJ2K . j2k . codestream . Markers . SQCX_GB_SHIFT ) ) ) ;
// SPqcc
switch ( qstyle )
{
case CSJ2K . j2k . codestream . Markers . SQCX_NO_QUANTIZATION :
// Get resolution level 0 subband
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Output one exponent per subband
for ( int j = 0 ; j < = mrl ; j + + )
{
sb2 = sb ;
while ( sb2 ! = null )
{
int tmp = ( imgnr + sb2 . anGainExp ) ;
hbuf . Write ( ( System . Byte ) ( tmp < < CSJ2K . j2k . codestream . Markers . SQCX_EXP_SHIFT ) ) ;
sb2 = ( SubbandAn ) sb2 . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_DERIVED :
// Get resolution level 0 subband
sb = sbRoot ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / ( 1 < < sb . level ) ;
// Write exponent-mantissa, 16 bits
hbuf . Write ( ( System . Int16 ) StdQuantizer . convertToExpMantissa ( step ) ) ;
break ;
case CSJ2K . j2k . codestream . Markers . SQCX_SCALAR_EXPOUNDED :
// Get resolution level 0 subband
sb = sbRoot ;
mrl = sb . resLvl ;
sb = ( SubbandAn ) sb . getSubbandByIdx ( 0 , 0 ) ;
for ( int j = 0 ; j < = mrl ; j + + )
{
sb2 = sb ;
while ( sb2 ! = null )
{
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / ( sb2 . l2Norm * ( 1 < < sb2 . anGainExp ) ) ;
// Write exponent-mantissa, 16 bits
hbuf . Write ( ( System . Int16 ) StdQuantizer . convertToExpMantissa ( step ) ) ;
sb2 = ( SubbandAn ) sb2 . nextSubband ( ) ;
}
// Go up one resolution level
sb = ( SubbandAn ) sb . NextResLevel ;
}
break ;
default :
2017-05-16 19:41:03 -05:00
throw new System . InvalidOperationException ( "Internal JJ2000 error" ) ;
2009-09-30 23:50:03 +00:00
}
}
/// <summary> Writes POC marker segment. POC is a functional marker segment
/// containing the bounds and progression order for any progression order
/// other than default in the codestream.
///
/// </summary>
/// <param name="mh">Flag indicating whether the main header is to be written
///
/// </param>
/// <param name="tileIdx">Tile index
///
/// </param>
protected internal virtual void writePOC ( bool mh , int tileIdx )
{
int markSegLen = 0 ; // Segment marker length
int lenCompField ; // Holds the size of any component field as
// this size depends on the number of
//components
Progression [ ] prog = null ; // Holds the progression(s)
int npoc ; // Number of progression order changes
// Get the progression order changes, their number and checks
// if it is ok
if ( mh )
{
prog = ( Progression [ ] ) ( encSpec . pocs . getDefault ( ) ) ;
}
else
{
prog = ( Progression [ ] ) ( encSpec . pocs . getTileDef ( tileIdx ) ) ;
}
// Calculate the length of a component field (depends on the number of
// components)
lenCompField = ( nComp < 257 ? 1 : 2 ) ;
// POC marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . POC ) ;
// Lpoc (marker segment length (in bytes))
// Basic: Lpoc(2 bytes) + npoc * [ RSpoc(1) + CSpoc(1 or 2) +
// LYEpoc(2) + REpoc(1) + CEpoc(1 or 2) + Ppoc(1) ]
npoc = prog . Length ;
markSegLen = 2 + npoc * ( 1 + lenCompField + 2 + 1 + lenCompField + 1 ) ;
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Write each progression order change
for ( int i = 0 ; i < npoc ; i + + )
{
// RSpoc(i)
hbuf . Write ( ( System . Byte ) prog [ i ] . rs ) ;
// CSpoc(i)
if ( lenCompField = = 2 )
{
hbuf . Write ( ( System . Int16 ) prog [ i ] . cs ) ;
}
else
{
hbuf . Write ( ( System . Byte ) prog [ i ] . cs ) ;
}
// LYEpoc(i)
hbuf . Write ( ( System . Int16 ) prog [ i ] . lye ) ;
// REpoc(i)
hbuf . Write ( ( System . Byte ) prog [ i ] . re ) ;
// CEpoc(i)
if ( lenCompField = = 2 )
{
hbuf . Write ( ( System . Int16 ) prog [ i ] . ce ) ;
}
else
{
hbuf . Write ( ( System . Byte ) prog [ i ] . ce ) ;
}
// Ppoc(i)
hbuf . Write ( ( System . Byte ) prog [ i ] . type ) ;
}
}
/// <summary> Write main header. JJ2000 main header corresponds to the following
/// sequence of marker segments:
///
/// <ol>
/// <li>SOC</li>
/// <li>SIZ</li>
/// <li>COD</li>
/// <li>COC (if needed)</li>
/// <li>QCD</li>
/// <li>QCC (if needed)</li>
/// <li>POC (if needed)</li>
/// </ol>
///
/// </summary>
public virtual void encodeMainHeader ( )
{
int i ;
// +---------------------------------+
// | SOC marker segment |
// +---------------------------------+
writeSOC ( ) ;
// +---------------------------------+
// | Image and tile SIZe (SIZ) |
// +---------------------------------+
writeSIZ ( ) ;
// +-------------------------------+
// | COding style Default (COD) |
// +-------------------------------+
bool isEresUsed = ( ( System . String ) encSpec . tts . getDefault ( ) ) . Equals ( "predict" ) ;
writeCOD ( true , 0 ) ;
// +---------------------------------+
// | COding style Component (COC) |
// +---------------------------------+
for ( i = 0 ; i < nComp ; i + + )
{
bool isEresUsedinComp = ( ( System . String ) encSpec . tts . getCompDef ( i ) ) . Equals ( "predict" ) ;
if ( encSpec . wfs . isCompSpecified ( i ) | | encSpec . dls . isCompSpecified ( i ) | | encSpec . bms . isCompSpecified ( i ) | | encSpec . mqrs . isCompSpecified ( i ) | | encSpec . rts . isCompSpecified ( i ) | | encSpec . sss . isCompSpecified ( i ) | | encSpec . css . isCompSpecified ( i ) | | encSpec . pss . isCompSpecified ( i ) | | encSpec . cblks . isCompSpecified ( i ) | | ( isEresUsed ! = isEresUsedinComp ) )
// Some component non-default stuff => need COC
writeCOC ( true , 0 , i ) ;
}
// +-------------------------------+
// | Quantization Default (QCD) |
// +-------------------------------+
writeMainQCD ( ) ;
// +-------------------------------+
// | Quantization Component (QCC) |
// +-------------------------------+
// Write needed QCC markers
for ( i = 0 ; i < nComp ; i + + )
{
if ( dwt . getNomRangeBits ( i ) ! = defimgn | | encSpec . qts . isCompSpecified ( i ) | | encSpec . qsss . isCompSpecified ( i ) | | encSpec . dls . isCompSpecified ( i ) | | encSpec . gbs . isCompSpecified ( i ) )
{
writeMainQCC ( i ) ;
}
}
// +--------------------------+
// | POC maker segment |
// +--------------------------+
Progression [ ] prog = ( Progression [ ] ) ( encSpec . pocs . getDefault ( ) ) ;
if ( prog . Length > 1 )
writePOC ( true , 0 ) ;
// +---------------------------+
// | Comments (COM) |
// +---------------------------+
writeCOM ( ) ;
}
/// <summary> Write COM marker segment(s) to the codestream.
///
/// <p>This marker is currently written in main header and indicates the
/// JJ2000 encoder's version that has created the codestream.</p>
///
/// </summary>
private void writeCOM ( )
{
// JJ2000 COM marker segment
if ( enJJ2KMarkSeg )
{
System . String str = "Created by: CSJ2K version " + JJ2KInfo . version ;
int markSegLen ; // the marker segment length
// COM marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . COM ) ;
// Calculate length: Lcom(2) + Rcom (2) + string's length;
markSegLen = 2 + 2 + str . Length ;
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Rcom
hbuf . Write ( ( System . Int16 ) 1 ) ; // General use (IS 8859-15:1999(Latin) values)
2017-05-16 19:41:03 -05:00
byte [ ] chars = System . Text . Encoding . UTF8 . GetBytes ( str ) ;
2009-09-30 23:50:03 +00:00
for ( int i = 0 ; i < chars . Length ; i + + )
{
hbuf . Write ( ( byte ) chars [ i ] ) ;
}
}
// other COM marker segments
if ( otherCOMMarkSeg ! = null )
{
SupportClass . Tokenizer stk = new SupportClass . Tokenizer ( otherCOMMarkSeg , "#" ) ;
while ( stk . HasMoreTokens ( ) )
{
System . String str = stk . NextToken ( ) ;
int markSegLen ; // the marker segment length
// COM marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . COM ) ;
// Calculate length: Lcom(2) + Rcom (2) + string's length;
markSegLen = 2 + 2 + str . Length ;
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Rcom
hbuf . Write ( ( System . Int16 ) 1 ) ; // General use (IS 8859-15:1999(Latin)
// values)
2017-05-16 19:41:03 -05:00
byte [ ] chars = System . Text . Encoding . UTF8 . GetBytes ( str ) ;
2009-09-30 23:50:03 +00:00
for ( int i = 0 ; i < chars . Length ; i + + )
{
hbuf . Write ( ( byte ) chars [ i ] ) ;
}
}
}
}
/// <summary> Writes the RGN marker segment in the tile header. It describes the
/// scaling value in each tile component
///
/// <p>May be used in tile or main header. If used in main header, it
/// refers to a ROI of the whole image, regardless of tiling. When used in
/// tile header, only the particular tile is affected.</p>
///
/// </summary>
/// <param name="tIdx">The tile index
///
/// </param>
/// <exception cref="IOException">If an I/O error occurs while reading from the
/// encoder header stream
///
/// </exception>
private void writeRGN ( int tIdx )
{
int i ;
int markSegLen ; // the marker length
// Write one RGN marker per component
for ( i = 0 ; i < nComp ; i + + )
{
// RGN marker
hbuf . Write ( ( System . Int16 ) CSJ2K . j2k . codestream . Markers . RGN ) ;
// Calculate length (Lrgn)
// Basic: Lrgn (2) + Srgn (1) + SPrgn + one byte
// or two for component number
markSegLen = 4 + ( ( nComp < 257 ) ? 1 : 2 ) ;
hbuf . Write ( ( System . Int16 ) markSegLen ) ;
// Write component (Crgn)
if ( nComp < 257 )
{
hbuf . Write ( ( System . Byte ) i ) ;
}
else
{
hbuf . Write ( ( System . Int16 ) i ) ;
}
// Write type of ROI (Srgn)
hbuf . Write ( ( System . Byte ) CSJ2K . j2k . codestream . Markers . SRGN_IMPLICIT ) ;
// Write ROI info (SPrgn)
hbuf . Write ( ( System . Byte ) ( ( System . Int32 ) ( encSpec . rois . getTileCompVal ( tIdx , i ) ) ) ) ;
}
}
/// <summary> Writes tile-part header. JJ2000 tile-part header corresponds to the
/// following sequence of marker segments:
///
/// <ol>
/// <li>SOT</li>
/// <li>COD (if needed)</li>
/// <li>COC (if needed)</li>
/// <li>QCD (if needed)</li>
/// <li>QCC (if needed)</li>
/// <li>RGN (if needed)</li>
/// <li>POC (if needed)</li>
/// <li>SOD</li>
/// </ol>
///
/// </summary>
/// <param name="length">The length of the current tile-part.
///
/// </param>
/// <param name="tileIdx">Index of the tile to write
///
/// </param>
public virtual void encodeTilePartHeader ( int tileLength , int tileIdx )
{
int tmp ;
Coord numTiles = ralloc . getNumTiles ( null ) ;
ralloc . setTile ( tileIdx % numTiles . x , tileIdx / numTiles . x ) ;
// +--------------------------+
// | SOT maker segment |
// +--------------------------+
// SOT marker
hbuf . Write ( ( System . Byte ) SupportClass . URShift ( CSJ2K . j2k . codestream . Markers . SOT , 8 ) ) ;
hbuf . Write ( ( System . Byte ) ( CSJ2K . j2k . codestream . Markers . SOT & 0x00FF ) ) ;
// Lsot (10 bytes)
hbuf . Write ( ( System . Byte ) 0 ) ;
hbuf . Write ( ( System . Byte ) 10 ) ;
// Isot
if ( tileIdx > 65534 )
{
throw new System . ArgumentException ( "Trying to write a tile-part " + "header whose tile index is " + "too high" ) ;
}
hbuf . Write ( ( System . Byte ) ( tileIdx > > 8 ) ) ;
hbuf . Write ( ( System . Byte ) tileIdx ) ;
// Psot
tmp = tileLength ;
hbuf . Write ( ( System . Byte ) ( tmp > > 24 ) ) ;
hbuf . Write ( ( System . Byte ) ( tmp > > 16 ) ) ;
hbuf . Write ( ( System . Byte ) ( tmp > > 8 ) ) ;
hbuf . Write ( ( System . Byte ) tmp ) ;
// TPsot
hbuf . Write ( ( System . Byte ) 0 ) ; // Only one tile-part currently supported !
// TNsot
hbuf . Write ( ( System . Byte ) 1 ) ; // Only one tile-part currently supported !
// +--------------------------+
// | COD maker segment |
// +--------------------------+
bool isEresUsed = ( ( System . String ) encSpec . tts . getDefault ( ) ) . Equals ( "predict" ) ;
bool isEresUsedInTile = ( ( System . String ) encSpec . tts . getTileDef ( tileIdx ) ) . Equals ( "predict" ) ;
bool tileCODwritten = false ;
if ( encSpec . wfs . isTileSpecified ( tileIdx ) | | encSpec . cts . isTileSpecified ( tileIdx ) | | encSpec . dls . isTileSpecified ( tileIdx ) | | encSpec . bms . isTileSpecified ( tileIdx ) | | encSpec . mqrs . isTileSpecified ( tileIdx ) | | encSpec . rts . isTileSpecified ( tileIdx ) | | encSpec . css . isTileSpecified ( tileIdx ) | | encSpec . pss . isTileSpecified ( tileIdx ) | | encSpec . sops . isTileSpecified ( tileIdx ) | | encSpec . sss . isTileSpecified ( tileIdx ) | | encSpec . pocs . isTileSpecified ( tileIdx ) | | encSpec . ephs . isTileSpecified ( tileIdx ) | | encSpec . cblks . isTileSpecified ( tileIdx ) | | ( isEresUsed ! = isEresUsedInTile ) )
{
writeCOD ( false , tileIdx ) ;
tileCODwritten = true ;
}
// +--------------------------+
// | COC maker segment |
// +--------------------------+
for ( int c = 0 ; c < nComp ; c + + )
{
bool isEresUsedInTileComp = ( ( System . String ) encSpec . tts . getTileCompVal ( tileIdx , c ) ) . Equals ( "predict" ) ;
if ( encSpec . wfs . isTileCompSpecified ( tileIdx , c ) | | encSpec . dls . isTileCompSpecified ( tileIdx , c ) | | encSpec . bms . isTileCompSpecified ( tileIdx , c ) | | encSpec . mqrs . isTileCompSpecified ( tileIdx , c ) | | encSpec . rts . isTileCompSpecified ( tileIdx , c ) | | encSpec . css . isTileCompSpecified ( tileIdx , c ) | | encSpec . pss . isTileCompSpecified ( tileIdx , c ) | | encSpec . sss . isTileCompSpecified ( tileIdx , c ) | | encSpec . cblks . isTileCompSpecified ( tileIdx , c ) | | ( isEresUsedInTileComp ! = isEresUsed ) )
{
writeCOC ( false , tileIdx , c ) ;
}
else if ( tileCODwritten )
{
if ( encSpec . wfs . isCompSpecified ( c ) | | encSpec . dls . isCompSpecified ( c ) | | encSpec . bms . isCompSpecified ( c ) | | encSpec . mqrs . isCompSpecified ( c ) | | encSpec . rts . isCompSpecified ( c ) | | encSpec . sss . isCompSpecified ( c ) | | encSpec . css . isCompSpecified ( c ) | | encSpec . pss . isCompSpecified ( c ) | | encSpec . cblks . isCompSpecified ( c ) | | ( encSpec . tts . isCompSpecified ( c ) & & ( ( System . String ) encSpec . tts . getCompDef ( c ) ) . Equals ( "predict" ) ) )
{
writeCOC ( false , tileIdx , c ) ;
}
}
}
// +--------------------------+
// | QCD maker segment |
// +--------------------------+
bool tileQCDwritten = false ;
if ( encSpec . qts . isTileSpecified ( tileIdx ) | | encSpec . qsss . isTileSpecified ( tileIdx ) | | encSpec . dls . isTileSpecified ( tileIdx ) | | encSpec . gbs . isTileSpecified ( tileIdx ) )
{
writeTileQCD ( tileIdx ) ;
tileQCDwritten = true ;
}
else
{
deftilenr = defimgn ;
}
// +--------------------------+
// | QCC maker segment |
// +--------------------------+
for ( int c = 0 ; c < nComp ; c + + )
{
if ( dwt . getNomRangeBits ( c ) ! = deftilenr | | encSpec . qts . isTileCompSpecified ( tileIdx , c ) | | encSpec . qsss . isTileCompSpecified ( tileIdx , c ) | | encSpec . dls . isTileCompSpecified ( tileIdx , c ) | | encSpec . gbs . isTileCompSpecified ( tileIdx , c ) )
{
writeTileQCC ( tileIdx , c ) ;
}
else if ( tileQCDwritten )
{
if ( encSpec . qts . isCompSpecified ( c ) | | encSpec . qsss . isCompSpecified ( c ) | | encSpec . dls . isCompSpecified ( c ) | | encSpec . gbs . isCompSpecified ( c ) )
{
writeTileQCC ( tileIdx , c ) ;
}
}
}
// +--------------------------+
// | RGN maker segment |
// +--------------------------+
if ( roiSc . useRoi ( ) & & ( ! roiSc . BlockAligned ) )
writeRGN ( tileIdx ) ;
// +--------------------------+
// | POC maker segment |
// +--------------------------+
Progression [ ] prog ;
if ( encSpec . pocs . isTileSpecified ( tileIdx ) )
{
prog = ( Progression [ ] ) ( encSpec . pocs . getTileDef ( tileIdx ) ) ;
if ( prog . Length > 1 )
writePOC ( false , tileIdx ) ;
}
// +--------------------------+
// | SOD maker |
// +--------------------------+
hbuf . Write ( ( System . Byte ) SupportClass . URShift ( CSJ2K . j2k . codestream . Markers . SOD , 8 ) ) ;
hbuf . Write ( ( System . Byte ) ( CSJ2K . j2k . codestream . Markers . SOD & 0x00FF ) ) ;
}
}
}