/* * CVS identifier: * * $Id: HeaderDecoder.java,v 1.61 2002/07/25 15:01:00 grosbois Exp $ * * Class: HeaderDecoder * * Description: Reads main and tile-part headers. * * * * 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.quantization.dequantizer; using CSJ2K.j2k.wavelet.synthesis; using CSJ2K.j2k.entropy.decoder; using CSJ2K.j2k.quantization; using CSJ2K.j2k.codestream; using CSJ2K.j2k.wavelet; using CSJ2K.j2k.entropy; using CSJ2K.j2k.decoder; using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.j2k.roi; using CSJ2K.j2k.io; using CSJ2K.j2k; using CSJ2K.Color; using CSJ2K.Icc; namespace CSJ2K.j2k.codestream.reader { /// This class reads main and tile-part headers from the codestream given a /// RandomAccessIO instance located at the beginning of the codestream (i.e /// just before the SOC marker) or at the beginning of a tile-part (i.e. just /// before a SOT marker segment) respectively. /// ///

A marker segment includes a marker and eventually marker segment /// parameters. It is designed by the three letters code of the marker /// associated with the marker segment. JPEG 2000 part 1 defines 6 types of /// markers segments: /// ///

/// ///

The main header is read when the constructor is called whereas tile-part /// headers are read when the FileBitstreamReaderAgent instance is created. The /// reading is done in 2 passes: /// ///

    ///
  1. All marker segments are buffered and their corresponding flag is /// activated (extractMainMarkSeg and extractTilePartMarkSeg methods).
  2. /// ///
  3. Buffered marker segment are analyzed in a logical way and /// specifications are stored in appropriate member of DecoderSpecs instance /// (readFoundMainMarkSeg and readFoundTilePartMarkSeg methods).
  4. ///

/// ///

Whenever a marker segment is not recognized a warning message is /// displayed and its length parameter is used to skip it.

/// ///

The information found in this header is stored in HeaderInfo and /// DecoderSpecs instances.

/// ///
/// /// /// /// /// /// /// /// /// public class HeaderDecoder { /// Return the maximum height among all components /// /// /// Maximum component height /// /// virtual public int MaxCompImgHeight { get { return hi.sizValue.MaxCompHeight; } } /// Return the maximum width among all components /// /// /// Maximum component width /// /// virtual public int MaxCompImgWidth { get { return hi.sizValue.MaxCompWidth; } } /// Returns the image width in the reference grid. /// /// /// The image width in the reference grid /// /// virtual public int ImgWidth { get { return hi.sizValue.xsiz - hi.sizValue.x0siz; } } /// Returns the image height in the reference grid. /// /// /// The image height in the reference grid /// /// virtual public int ImgHeight { get { return hi.sizValue.ysiz - hi.sizValue.y0siz; } } /// Return the horizontal upper-left coordinate of the image in the /// reference grid. /// /// /// The horizontal coordinate of the image origin. /// /// virtual public int ImgULX { get { return hi.sizValue.x0siz; } } /// Return the vertical upper-left coordinate of the image in the reference /// grid. /// /// /// The vertical coordinate of the image origin. /// /// virtual public int ImgULY { get { return hi.sizValue.y0siz; } } /// Returns the nominal width of the tiles in the reference grid. /// /// /// The nominal tile width, in the reference grid. /// /// virtual public int NomTileWidth { get { return hi.sizValue.xtsiz; } } /// Returns the nominal width of the tiles in the reference grid. /// /// /// The nominal tile width, in the reference grid. /// /// virtual public int NomTileHeight { get { return hi.sizValue.ytsiz; } } /// Returns the number of components in the image. /// /// /// The number of components in the image. /// /// virtual public int NumComps { get { return nComp; } } /// Returns the horizontal code-block partition origin.Allowable values are /// 0 and 1, nothing else. /// /// virtual public int CbULX { get { return cb0x; } } /// Returns the vertical code-block partition origin. Allowable values are /// 0 and 1, nothing else. /// /// virtual public int CbULY { get { return cb0y; } } /// Return the DecoderSpecs instance filled when reading the headers /// /// /// The DecoderSpecs of the decoder /// /// virtual public DecoderSpecs DecoderSpecs { get { return decSpec; } } /// Returns the parameters that are used in this class. 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 and the third one is a long description of what the /// parameter is. The synopsis or description may be 'null', in which case /// it is assumed that there is no synopsis or description of the option, /// respectively. /// /// /// the options name, their synopsis and their explanation. /// /// public static System.String[][] ParameterInfo { get { return pinfo; } } /// Return the number of tiles in the image /// /// /// The number of tiles /// /// virtual public int NumTiles { get { return nTiles; } } /// Sets the tile of each tile part in order. This information is needed /// for identifying which packet header belongs to which tile when using /// the PPM marker. /// /// /// The tile number that the present tile part belongs to. /// /// virtual public int TileOfTileParts { set { if (nPPMMarkSeg != 0) { tileOfTileParts.Add((System.Int32) value); } } } /// Returns the number of found marker segments in the current header. /// /// /// The number of marker segments found in the current header. /// /// virtual public int NumFoundMarkSeg { get { return nfMarkSeg; } } /// The prefix for header decoder options: 'H' public const char OPT_PREFIX = 'H'; /// The list of parameters that is accepted for quantization. Options /// for quantization start with 'Q'. /// //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 = null; /// The reference to the HeaderInfo instance holding the information found /// in headers /// private HeaderInfo hi; /// Whether or not to display general information //private bool verbose; /// Current header information in a string private System.String hdStr = ""; /// The number of tiles within the image private int nTiles; /// The number of tile parts in each tile public int[] nTileParts; /// Used to store which markers have been already read, by using flag /// bits. The different markers are marked with XXX_FOUND flags, such as /// SIZ_FOUND /// private int nfMarkSeg = 0; /// Counts number of COC markers found in the header private int nCOCMarkSeg = 0; /// Counts number of QCC markers found in the header private int nQCCMarkSeg = 0; /// Counts number of COM markers found in the header private int nCOMMarkSeg = 0; /// Counts number of RGN markers found in the header private int nRGNMarkSeg = 0; /// Counts number of PPM markers found in the header private int nPPMMarkSeg = 0; /// Counts number of PPT markers found in the header private int[][] nPPTMarkSeg = null; /// Flag bit for SIZ marker segment found private const int SIZ_FOUND = 1; /// Flag bit for COD marker segment found private const int COD_FOUND = 1 << 1; /// Flag bit for COC marker segment found private const int COC_FOUND = 1 << 2; /// Flag bit for QCD marker segment found private const int QCD_FOUND = 1 << 3; /// Flag bit for TLM marker segment found private const int TLM_FOUND = 1 << 4; /// Flag bit for PLM marker segment found private const int PLM_FOUND = 1 << 5; /// Flag bit for SOT marker segment found private const int SOT_FOUND = 1 << 6; /// Flag bit for PLT marker segment found private const int PLT_FOUND = 1 << 7; /// Flag bit for QCC marker segment found private const int QCC_FOUND = 1 << 8; /// Flag bit for RGN marker segment found private const int RGN_FOUND = 1 << 9; /// Flag bit for POC marker segment found private const int POC_FOUND = 1 << 10; /// Flag bit for COM marker segment found private const int COM_FOUND = 1 << 11; /// Flag bit for SOD marker segment found public const int SOD_FOUND = 1 << 13; /// Flag bit for SOD marker segment found public const int PPM_FOUND = 1 << 14; /// Flag bit for SOD marker segment found public const int PPT_FOUND = 1 << 15; /// Flag bit for CRG marker segment found public const int CRG_FOUND = 1 << 16; /// The reset mask for new tiles //UPGRADE_NOTE: Final was removed from the declaration of 'TILE_RESET '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" //private static readonly int TILE_RESET = ~ (PLM_FOUND | SIZ_FOUND | RGN_FOUND); /// HashTable used to store temporary marker segment byte buffers private System.Collections.Hashtable ht = null; /// The number of components in the image private int nComp; /// The horizontal code-block partition origin private int cb0x = - 1; /// The vertical code-block partition origin private int cb0y = - 1; /// The decoder specifications private DecoderSpecs decSpec; /// Is the precinct partition used internal bool precinctPartitionIsUsed; /// The offset of the main header in the input stream public int mainHeadOff; /// Vector containing info as to which tile each tilepart belong private System.Collections.ArrayList tileOfTileParts; /// Array containing the Nppm and Ippm fields of the PPM marker segments private byte[][] pPMMarkerData; /// Array containing the Ippm fields of the PPT marker segments private byte[][][][] tilePartPkdPktHeaders; /// The packed packet headers if the PPM or PPT markers are used private System.IO.MemoryStream[] pkdPktHeaders; /// Returns the tiling origin, referred to as '(Px,Py)' in the 'ImgData' /// interface. /// /// /// If not null this object is used to return the information. If /// null a new one is created and returned. /// /// /// The coordinate of the tiling origin, in the canvas system, on /// the reference grid. /// /// /// /// /// public Coord getTilingOrigin(Coord co) { if (co != null) { co.x = hi.sizValue.xt0siz; co.y = hi.sizValue.yt0siz; return co; } else { return new Coord(hi.sizValue.xt0siz, hi.sizValue.yt0siz); } } /// Returns true if the original data of the specified component was /// signed. If the data was not signed a level shift has to be applied at /// the end of the decompression chain. /// /// /// The index of the component /// /// /// True if the original image component was signed. /// /// public bool isOriginalSigned(int c) { return hi.sizValue.isOrigSigned(c); } /// Returns the original bitdepth of the specified component. /// /// /// The index of the component /// /// /// The bitdepth of the component /// /// public int getOriginalBitDepth(int c) { return hi.sizValue.getOrigBitDepth(c); } /// Returns the component sub-sampling factor, with respect to the /// reference grid, along the horizontal direction for the specified /// component. /// /// /// The index of the component /// /// /// The component sub-sampling factor X-wise. /// /// public int getCompSubsX(int c) { return hi.sizValue.xrsiz[c]; } /// Returns the component sub-sampling factor, with respect to the /// reference grid, along the vertical direction for the specified /// component. /// /// /// The index of the component /// /// /// The component sub-sampling factor Y-wise. /// /// public int getCompSubsY(int c) { return hi.sizValue.yrsiz[c]; } /// Returns the dequantizer parameters. Dequantizer parameters normally are /// the quantization step sizes, see DequantizerParams. /// /// /// The source of data for the dequantizer. /// /// /// The number of range bits for each component. Must be /// the number of range bits of the mixed components. /// /// /// The DecoderSpecs instance after any image manipulation. /// /// /// The dequantizer /// /// public Dequantizer createDequantizer(CBlkQuantDataSrcDec src, int[] rb, DecoderSpecs decSpec2) { return new StdDequantizer(src, rb, decSpec2); } /// Returns the precinct partition width for the specified tile-component /// and resolution level. /// /// /// the component index /// /// /// the tile index /// /// /// the resolution level /// /// /// The precinct partition width for the specified tile-component /// and resolution level /// /// public int getPPX(int t, int c, int rl) { return decSpec.pss.getPPX(t, c, rl); } /// Returns the precinct partition height for the specified tile-component /// and resolution level. /// /// /// the component index /// /// /// the tile index /// /// /// the resolution level /// /// /// The precinct partition height for the specified tile-component /// and resolution level /// /// public int getPPY(int t, int c, int rl) { return decSpec.pss.getPPY(t, c, rl); } /// Returns the boolean used to know if the precinct partition is used /// /// public bool precinctPartitionUsed() { return precinctPartitionIsUsed; } /// Reads a wavelet filter from the codestream and returns the filter /// object that implements it. /// /// /// The encoded header stream from where to read the info /// /// /// Int array of one element to return the type of the /// wavelet filter. /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private SynWTFilter readFilter(System.IO.BinaryReader ehs, int[] filtIdx) { int kid; // the filter id kid = filtIdx[0] = ehs.ReadByte(); if (kid >= (1 << 7)) { throw new NotImplementedException("Custom filters not supported"); } // Return filter based on ID switch (kid) { case CSJ2K.j2k.wavelet.FilterTypes_Fields.W9X7: return new SynWTFilterFloatLift9x7(); case CSJ2K.j2k.wavelet.FilterTypes_Fields.W5X3: return new SynWTFilterIntLift5x3(); default: throw new CorruptedCodestreamException("Specified wavelet filter " + "not" + " JPEG 2000 part I " + "compliant"); } } /// Checks that the marker segment length is correct. /// /// /// The encoded header stream /// /// /// The string identifying the marker, such as "SIZ marker" /// /// /// If an I/O error occurs /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" public virtual void checkMarkerLength(System.IO.BinaryReader ehs, System.String str) { long available; available = ehs.BaseStream.Length - ehs.BaseStream.Position; if ((int) available != 0) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, str + " length was short, attempting to resync."); } } /// Reads the SIZ marker segment and realigns the codestream at the point /// where the next marker segment should be found. /// ///

SIZ is a fixed information marker segment containing informations /// about image and tile sizes. It is required in the main header /// immediately after SOC.

/// ///
/// The encoded header stream /// /// /// If an I/O error occurs while reading from the /// encoded header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readSIZ(System.IO.BinaryReader ehs) { HeaderInfo.SIZ ms = hi.NewSIZ; hi.sizValue = ms; // Read the length of SIZ marker segment (Lsiz) ms.lsiz = ehs.ReadUInt16(); // Read the capability of the codestream (Rsiz) ms.rsiz = ehs.ReadUInt16(); if (ms.rsiz > 2) { throw new System.ApplicationException("Codestream capabiities not JPEG 2000 - Part I" + " compliant"); } // Read image size ms.xsiz = ehs.ReadInt32(); ms.ysiz = ehs.ReadInt32(); if (ms.xsiz <= 0 || ms.ysiz <= 0) { throw new System.IO.IOException("JJ2000 does not support images whose " + "width and/or height not in the " + "range: 1 -- (2^31)-1"); } // Read image offset ms.x0siz = ehs.ReadInt32(); ms.y0siz = ehs.ReadInt32(); if (ms.x0siz < 0 || ms.y0siz < 0) { throw new System.IO.IOException("JJ2000 does not support images offset " + "not in the range: 0 -- (2^31)-1"); } // Read size of tile ms.xtsiz = ehs.ReadInt32(); ms.ytsiz = ehs.ReadInt32(); if (ms.xtsiz <= 0 || ms.ytsiz <= 0) { throw new System.IO.IOException("JJ2000 does not support tiles whose " + "width and/or height are not in " + "the range: 1 -- (2^31)-1"); } // Read upper-left tile offset ms.xt0siz = ehs.ReadInt32(); ms.yt0siz = ehs.ReadInt32(); if (ms.xt0siz < 0 || ms.yt0siz < 0) { throw new System.IO.IOException("JJ2000 does not support tiles whose " + "offset is not in " + "the range: 0 -- (2^31)-1"); } // Read number of components and initialize related arrays nComp = ms.csiz = ehs.ReadUInt16(); if (nComp < 1 || nComp > 16384) { throw new System.ArgumentException("Number of component out of " + "range 1--16384: " + nComp); } ms.ssiz = new int[nComp]; ms.xrsiz = new int[nComp]; ms.yrsiz = new int[nComp]; // Read bit-depth and down-sampling factors of each component for (int i = 0; i < nComp; i++) { ms.ssiz[i] = ehs.ReadByte(); ms.xrsiz[i] = ehs.ReadByte(); ms.yrsiz[i] = ehs.ReadByte(); } // Check marker length checkMarkerLength(ehs, "SIZ marker"); // Create needed ModuleSpec nTiles = ms.NumTiles; // Finish initialization of decSpec decSpec = new DecoderSpecs(nTiles, nComp); } /// Reads a CRG marker segment and checks its length. CRG is an /// informational marker segment that allows specific registration of /// components with respect to each other. /// /// /// The encoded header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readCRG(System.IO.BinaryReader ehs) { HeaderInfo.CRG ms = hi.NewCRG; hi.crgValue = ms; ms.lcrg = ehs.ReadUInt16(); ms.xcrg = new int[nComp]; ms.ycrg = new int[nComp]; FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Information in CRG marker segment " + "not taken into account. This may affect the display " + "of the decoded image."); for (int c = 0; c < nComp; c++) { ms.xcrg[c] = ehs.ReadUInt16(); ms.ycrg[c] = ehs.ReadUInt16(); } // Check marker length checkMarkerLength(ehs, "CRG marker"); } /// Reads a COM marker segments and realigns the bit stream at the point /// where the next marker segment should be found. COM is an informational /// marker segment that allows to include unstructured data in the main and /// tile-part headers. /// /// /// The encoded header stream /// /// /// Flag indicating whether or not this marker segment is read /// from the main header. /// /// /// The index of the current tile /// /// /// Occurence of this COM marker in eith main or tile-part /// header /// /// /// If an I/O error occurs while reading from the /// encoded header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readCOM(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int comIdx) { HeaderInfo.COM ms = hi.NewCOM; // Read length of COM field ms.lcom = ehs.ReadUInt16(); // Read the registration value of the COM marker segment ms.rcom = ehs.ReadUInt16(); switch (ms.rcom) { case CSJ2K.j2k.codestream.Markers.RCOM_BINARY: case CSJ2K.j2k.codestream.Markers.RCOM_LATIN: ms.ccom = new byte[ms.lcom - 4]; for (int i = 0; i < ms.lcom - 4; i++) { ms.ccom[i] = ehs.ReadByte(); } break; default: // --- Unknown or unsupported markers --- // (skip them and see if we can get way with it) FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "COM marker registered as " + ms.rcom + " unknown, ignoring (this might crash the " + "decoder or decode a quality degraded or even " + "useless image)"); System.IO.BinaryReader temp_BinaryReader; System.Int64 temp_Int64; temp_BinaryReader = ehs; temp_Int64 = temp_BinaryReader.BaseStream.Position; temp_Int64 = temp_BinaryReader.BaseStream.Seek(ms.lcom - 4, System.IO.SeekOrigin.Current) - temp_Int64; // CONVERSION PROBLEM? int generatedAux2 = (int)temp_Int64; //Ignore this field for the moment break; } if (mainh) { hi.comValue["main_" + comIdx] = ms; } else { hi.comValue["t" + tileIdx + "_" + comIdx] = ms; } // Check marker length checkMarkerLength(ehs, "COM marker"); } /// Reads a QCD marker segment and realigns the codestream at the point /// where the next marker should be found. QCD is a functional marker /// segment that describes the quantization default. /// /// /// The encoded stream. /// /// /// Flag indicating whether or not this marker segment is read /// from the main header. /// /// /// The index of the current tile /// /// /// Tile-part index /// /// /// If an I/O error occurs while reading from the /// encoded header stream. /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readQCD(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int tpIdx) { StdDequantizerParams qParms; int guardBits; int[][] exp; float[][] nStep = null; HeaderInfo.QCD ms = hi.NewQCD; // Lqcd (length of QCD field) ms.lqcd = ehs.ReadUInt16(); // Sqcd (quantization style) ms.sqcd = ehs.ReadByte(); guardBits = ms.NumGuardBits; int qType = ms.QuantType; if (mainh) { hi.qcdValue["main"] = ms; // If the main header is being read set default value of // dequantization spec switch (qType) { case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: decSpec.qts.setDefault("reversible"); break; case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: decSpec.qts.setDefault("derived"); break; case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: decSpec.qts.setDefault("expounded"); break; default: throw new CorruptedCodestreamException("Unknown or " + "unsupported " + "quantization style " + "in Sqcd field, QCD " + "marker main header"); } } else { hi.qcdValue["t" + tileIdx] = ms; // If the tile header is being read set default value of // dequantization spec for tile switch (qType) { case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: decSpec.qts.setTileDef(tileIdx, "reversible"); break; case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: decSpec.qts.setTileDef(tileIdx, "derived"); break; case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: decSpec.qts.setTileDef(tileIdx, "expounded"); break; default: throw new CorruptedCodestreamException("Unknown or " + "unsupported " + "quantization style " + "in Sqcd field, QCD " + "marker, tile header"); } } qParms = new StdDequantizerParams(); if (qType == CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION) { int maxrl = (mainh?((System.Int32) decSpec.dls.getDefault()):((System.Int32) decSpec.dls.getTileDef(tileIdx))); int j, rl; // i removed int minb, maxb, hpd; int tmp; exp = qParms.exp = new int[maxrl + 1][]; int[][] tmpArray = new int[maxrl + 1][]; for (int i2 = 0; i2 < maxrl + 1; i2++) { tmpArray[i2] = new int[4]; } ms.spqcd = tmpArray; for (rl = 0; rl <= maxrl; rl++) { // Loop on resolution levels // Find the number of subbands in the resolution level if (rl == 0) { // Only the LL subband minb = 0; maxb = 1; } else { // Dyadic decomposition hpd = 1; // Adapt hpd to resolution level if (hpd > maxrl - rl) { hpd -= (maxrl - rl); } else { hpd = 1; } // Determine max and min subband index minb = 1 << ((hpd - 1) << 1); // minb = 4^(hpd-1) maxb = 1 << (hpd << 1); // maxb = 4^hpd } // Allocate array for subbands in resolution level exp[rl] = new int[maxb]; for (j = minb; j < maxb; j++) { tmp = ms.spqcd[rl][j] = ehs.ReadByte(); exp[rl][j] = (tmp >> CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT) & CSJ2K.j2k.codestream.Markers.SQCX_EXP_MASK; } } // end for rl } else { int maxrl = (qType == CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED)?0:(mainh?((System.Int32) decSpec.dls.getDefault()):((System.Int32) decSpec.dls.getTileDef(tileIdx))); int j, rl; // i removed int minb, maxb, hpd; int tmp; exp = qParms.exp = new int[maxrl + 1][]; nStep = qParms.nStep = new float[maxrl + 1][]; int[][] tmpArray2 = new int[maxrl + 1][]; for (int i3 = 0; i3 < maxrl + 1; i3++) { tmpArray2[i3] = new int[4]; } ms.spqcd = tmpArray2; for (rl = 0; rl <= maxrl; rl++) { // Loop on resolution levels // Find the number of subbands in the resolution level if (rl == 0) { // Only the LL subband minb = 0; maxb = 1; } else { // Dyadic decomposition hpd = 1; // Adapt hpd to resolution level if (hpd > maxrl - rl) { hpd -= (maxrl - rl); } else { hpd = 1; } // Determine max and min subband index minb = 1 << ((hpd - 1) << 1); // minb = 4^(hpd-1) maxb = 1 << (hpd << 1); // maxb = 4^hpd } // Allocate array for subbands in resolution level exp[rl] = new int[maxb]; nStep[rl] = new float[maxb]; for (j = minb; j < maxb; j++) { tmp = ms.spqcd[rl][j] = ehs.ReadUInt16(); exp[rl][j] = (tmp >> 11) & 0x1f; // NOTE: the formula below does not support more than 5 // bits for the exponent, otherwise (-1< Reads a QCC marker segment and realigns the codestream at the point /// where the next marker should be found. QCC is a functional marker /// segment that describes the quantization of one component. /// /// /// The encoded stream. /// /// /// Flag indicating whether or not this marker segment is read /// from the main header. /// /// /// The index of the current tile /// /// /// Tile-part index /// /// /// If an I/O error occurs while reading from the /// encoded header stream. /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readQCC(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int tpIdx) { int cComp; // current component int tmp; StdDequantizerParams qParms; int[][] expC; float[][] nStepC = null; HeaderInfo.QCC ms = hi.NewQCC; // Lqcc (length of QCC field) ms.lqcc = ehs.ReadUInt16(); // Cqcc if (nComp < 257) { cComp = ms.cqcc = ehs.ReadByte(); } else { cComp = ms.cqcc = ehs.ReadUInt16(); } if (cComp >= nComp) { throw new CorruptedCodestreamException("Invalid component " + "index in QCC marker"); } // Sqcc (quantization style) ms.sqcc = ehs.ReadByte(); int guardBits = ms.NumGuardBits; int qType = ms.QuantType; if (mainh) { hi.qccValue["main_c" + cComp] = ms; // If main header is being read, set default for component in all // tiles switch (qType) { case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: decSpec.qts.setCompDef(cComp, "reversible"); break; case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: decSpec.qts.setCompDef(cComp, "derived"); break; case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: decSpec.qts.setCompDef(cComp, "expounded"); break; default: throw new CorruptedCodestreamException("Unknown or " + "unsupported " + "quantization style " + "in Sqcd field, QCD " + "marker, main header"); } } else { hi.qccValue["t" + tileIdx + "_c" + cComp] = ms; // If tile header is being read, set value for component in // this tiles switch (qType) { case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: decSpec.qts.setTileCompVal(tileIdx, cComp, "reversible"); break; case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: decSpec.qts.setTileCompVal(tileIdx, cComp, "derived"); break; case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: decSpec.qts.setTileCompVal(tileIdx, cComp, "expounded"); break; default: throw new CorruptedCodestreamException("Unknown or " + "unsupported " + "quantization style " + "in Sqcd field, QCD " + "marker, main header"); } } // Decode all dequantizer params qParms = new StdDequantizerParams(); if (qType == CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION) { int maxrl = (mainh?((System.Int32) decSpec.dls.getCompDef(cComp)):((System.Int32) decSpec.dls.getTileCompVal(tileIdx, cComp))); int j, rl; // i removed int minb, maxb, hpd; expC = qParms.exp = new int[maxrl + 1][]; int[][] tmpArray = new int[maxrl + 1][]; for (int i2 = 0; i2 < maxrl + 1; i2++) { tmpArray[i2] = new int[4]; } ms.spqcc = tmpArray; for (rl = 0; rl <= maxrl; rl++) { // Loop on resolution levels // Find the number of subbands in the resolution level if (rl == 0) { // Only the LL subband minb = 0; maxb = 1; } else { // Dyadic decomposition hpd = 1; // Adapt hpd to resolution level if (hpd > maxrl - rl) { hpd -= (maxrl - rl); } else { hpd = 1; } // Determine max and min subband index minb = 1 << ((hpd - 1) << 1); // minb = 4^(hpd-1) maxb = 1 << (hpd << 1); // maxb = 4^hpd } // Allocate array for subbands in resolution level expC[rl] = new int[maxb]; for (j = minb; j < maxb; j++) { tmp = ms.spqcc[rl][j] = ehs.ReadByte(); expC[rl][j] = (tmp >> CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT) & CSJ2K.j2k.codestream.Markers.SQCX_EXP_MASK; } } // end for rl } else { int maxrl = (qType == CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED)?0:(mainh?((System.Int32) decSpec.dls.getCompDef(cComp)):((System.Int32) decSpec.dls.getTileCompVal(tileIdx, cComp))); int j, rl; // i removed int minb, maxb, hpd; nStepC = qParms.nStep = new float[maxrl + 1][]; expC = qParms.exp = new int[maxrl + 1][]; int[][] tmpArray2 = new int[maxrl + 1][]; for (int i3 = 0; i3 < maxrl + 1; i3++) { tmpArray2[i3] = new int[4]; } ms.spqcc = tmpArray2; for (rl = 0; rl <= maxrl; rl++) { // Loop on resolution levels // Find the number of subbands in the resolution level if (rl == 0) { // Only the LL subband minb = 0; maxb = 1; } else { // Dyadic decomposition hpd = 1; // Adapt hpd to resolution level if (hpd > maxrl - rl) { hpd -= (maxrl - rl); } else { hpd = 1; } // Determine max and min subband index minb = 1 << ((hpd - 1) << 1); // minb = 4^(hpd-1) maxb = 1 << (hpd << 1); // maxb = 4^hpd } // Allocate array for subbands in resolution level expC[rl] = new int[maxb]; nStepC[rl] = new float[maxb]; for (j = minb; j < maxb; j++) { tmp = ms.spqcc[rl][j] = ehs.ReadUInt16(); expC[rl][j] = (tmp >> 11) & 0x1f; // NOTE: the formula below does not support more than 5 // bits for the exponent, otherwise (-1< Reads a COD marker segment and realigns the codestream where the next /// marker should be found. /// /// /// The encoder header stream. /// /// /// Flag indicating whether or not this marker segment is read /// from the main header. /// /// /// The index of the current tile /// /// /// Tile-part index /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readCOD(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int tpIdx) { int cstyle; // The block style SynWTFilter[] hfilters, vfilters; //int l; System.Int32[] cblk; System.String errMsg; //bool sopUsed = false; //bool ephUsed = false; HeaderInfo.COD ms = hi.NewCOD; // Lcod (marker length) ms.lcod = ehs.ReadUInt16(); // Scod (block style) // We only support wavelet transformed data cstyle = ms.scod = ehs.ReadByte(); if ((cstyle & CSJ2K.j2k.codestream.Markers.SCOX_PRECINCT_PARTITION) != 0) { precinctPartitionIsUsed = true; // Remove flag cstyle &= ~ (CSJ2K.j2k.codestream.Markers.SCOX_PRECINCT_PARTITION); } else { precinctPartitionIsUsed = false; } // SOP markers if (mainh) { hi.codValue["main"] = ms; if ((cstyle & CSJ2K.j2k.codestream.Markers.SCOX_USE_SOP) != 0) { // SOP markers are used decSpec.sops.setDefault((System.Object) "true".ToUpper().Equals("TRUE")); //sopUsed = true; // Remove flag cstyle &= ~ (CSJ2K.j2k.codestream.Markers.SCOX_USE_SOP); } else { // SOP markers are not used decSpec.sops.setDefault((System.Object) "false".ToUpper().Equals("TRUE")); } } else { hi.codValue["t" + tileIdx] = ms; if ((cstyle & CSJ2K.j2k.codestream.Markers.SCOX_USE_SOP) != 0) { // SOP markers are used decSpec.sops.setTileDef(tileIdx, (System.Object) "true".ToUpper().Equals("TRUE")); //sopUsed = true; // Remove flag cstyle &= ~ (CSJ2K.j2k.codestream.Markers.SCOX_USE_SOP); } else { // SOP markers are not used decSpec.sops.setTileDef(tileIdx, (System.Object) "false".ToUpper().Equals("TRUE")); } } // EPH markers if (mainh) { if ((cstyle & CSJ2K.j2k.codestream.Markers.SCOX_USE_EPH) != 0) { // EPH markers are used decSpec.ephs.setDefault((System.Object) "true".ToUpper().Equals("TRUE")); //ephUsed = true; // Remove flag cstyle &= ~ (CSJ2K.j2k.codestream.Markers.SCOX_USE_EPH); } else { // EPH markers are not used decSpec.ephs.setDefault((System.Object) "false".ToUpper().Equals("TRUE")); } } else { if ((cstyle & CSJ2K.j2k.codestream.Markers.SCOX_USE_EPH) != 0) { // EPH markers are used decSpec.ephs.setTileDef(tileIdx, (System.Object) "true".ToUpper().Equals("TRUE")); //ephUsed = true; // Remove flag cstyle &= ~ (CSJ2K.j2k.codestream.Markers.SCOX_USE_EPH); } else { // EPH markers are not used decSpec.ephs.setTileDef(tileIdx, (System.Object) "false".ToUpper().Equals("TRUE")); } } // Code-block partition origin if ((cstyle & (CSJ2K.j2k.codestream.Markers.SCOX_HOR_CB_PART | CSJ2K.j2k.codestream.Markers.SCOX_VER_CB_PART)) != 0) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Code-block partition origin " + "different from (0,0). This is defined in JPEG 2000" + " part 2 and may not be supported by all JPEG " + "2000 decoders."); } if ((cstyle & CSJ2K.j2k.codestream.Markers.SCOX_HOR_CB_PART) != 0) { if (cb0x != - 1 && cb0x == 0) { throw new System.ArgumentException("Code-block partition " + "origin redefined in new" + " COD marker segment. Not" + " supported by JJ2000"); } cb0x = 1; cstyle &= ~ (CSJ2K.j2k.codestream.Markers.SCOX_HOR_CB_PART); } else { if (cb0x != - 1 && cb0x == 1) { throw new System.ArgumentException("Code-block partition " + "origin redefined in new" + " COD marker segment. Not" + " supported by JJ2000"); } cb0x = 0; } if ((cstyle & CSJ2K.j2k.codestream.Markers.SCOX_VER_CB_PART) != 0) { if (cb0y != - 1 && cb0y == 0) { throw new System.ArgumentException("Code-block partition " + "origin redefined in new" + " COD marker segment. Not" + " supported by JJ2000"); } cb0y = 1; cstyle &= ~ (CSJ2K.j2k.codestream.Markers.SCOX_VER_CB_PART); } else { if (cb0y != - 1 && cb0y == 1) { throw new System.ArgumentException("Code-block partition " + "origin redefined in new" + " COD marker segment. Not" + " supported by JJ2000"); } cb0y = 0; } // SGcod // Read the progressive order ms.sgcod_po = ehs.ReadByte(); // Read the number of layers ms.sgcod_nl = ehs.ReadUInt16(); if (ms.sgcod_nl <= 0 || ms.sgcod_nl > 65535) { throw new CorruptedCodestreamException("Number of layers out of " + "range: 1--65535"); } // Multiple component transform ms.sgcod_mct = ehs.ReadByte(); // SPcod // decomposition levels int mrl = ms.spcod_ndl = ehs.ReadByte(); if (mrl > 32) { throw new CorruptedCodestreamException("Number of decomposition " + "levels out of range: " + "0--32"); } // Read the code-blocks dimensions cblk = new System.Int32[2]; ms.spcod_cw = ehs.ReadByte(); cblk[0] = (System.Int32) (1 << (ms.spcod_cw + 2)); if (cblk[0] < CSJ2K.j2k.entropy.StdEntropyCoderOptions.MIN_CB_DIM || cblk[0] > CSJ2K.j2k.entropy.StdEntropyCoderOptions.MAX_CB_DIM) { errMsg = "Non-valid code-block width in SPcod field, " + "COD marker"; throw new CorruptedCodestreamException(errMsg); } ms.spcod_ch = ehs.ReadByte(); cblk[1] = (System.Int32) (1 << (ms.spcod_ch + 2)); if (cblk[1] < CSJ2K.j2k.entropy.StdEntropyCoderOptions.MIN_CB_DIM || cblk[1] > CSJ2K.j2k.entropy.StdEntropyCoderOptions.MAX_CB_DIM) { errMsg = "Non-valid code-block height in SPcod field, " + "COD marker"; throw new CorruptedCodestreamException(errMsg); } if ((cblk[0] * cblk[1]) > CSJ2K.j2k.entropy.StdEntropyCoderOptions.MAX_CB_AREA) { errMsg = "Non-valid code-block area in SPcod field, " + "COD marker"; throw new CorruptedCodestreamException(errMsg); } if (mainh) { decSpec.cblks.setDefault((System.Object) (cblk)); } else { decSpec.cblks.setTileDef(tileIdx, (System.Object) (cblk)); } // Style of the code-block coding passes int ecOptions = ms.spcod_cs = ehs.ReadByte(); if ((ecOptions & ~ (CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS)) != 0) { throw new CorruptedCodestreamException("Unknown \"code-block " + "style\" in SPcod field, " + "COD marker: 0x" + System.Convert.ToString(ecOptions, 16)); } // Read wavelet filter for tile or image hfilters = new SynWTFilter[1]; vfilters = new SynWTFilter[1]; hfilters[0] = readFilter(ehs, ms.spcod_t); vfilters[0] = hfilters[0]; // Fill the filter spec // If this is the main header, set the default value, if it is the // tile header, set default for this tile SynWTFilter[][] hvfilters = new SynWTFilter[2][]; hvfilters[0] = hfilters; hvfilters[1] = vfilters; // Get precinct partition sizes System.Collections.ArrayList[] v = new System.Collections.ArrayList[2]; v[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); v[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); int val = CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE; if (!precinctPartitionIsUsed) { System.Int32 w, h; w = (System.Int32) (1 << (val & 0x000F)); v[0].Add(w); h = (System.Int32) (1 << (((val & 0x00F0) >> 4))); v[1].Add(h); } else { ms.spcod_ps = new int[mrl + 1]; for (int rl = mrl; rl >= 0; rl--) { System.Int32 w, h; val = ms.spcod_ps[mrl - rl] = ehs.ReadByte(); w = (System.Int32) (1 << (val & 0x000F)); v[0].Insert(0, w); h = (System.Int32) (1 << (((val & 0x00F0) >> 4))); v[1].Insert(0, h); } } if (mainh) { decSpec.pss.setDefault(v); } else { decSpec.pss.setTileDef(tileIdx, v); } precinctPartitionIsUsed = true; // Check marker length checkMarkerLength(ehs, "COD marker"); // Store specifications in decSpec if (mainh) { decSpec.wfs.setDefault(hvfilters); decSpec.dls.setDefault((System.Object) mrl); decSpec.ecopts.setDefault((System.Object) ecOptions); decSpec.cts.setDefault((System.Object) ms.sgcod_mct); decSpec.nls.setDefault((System.Object) ms.sgcod_nl); decSpec.pos.setDefault((System.Object) ms.sgcod_po); } else { decSpec.wfs.setTileDef(tileIdx, hvfilters); decSpec.dls.setTileDef(tileIdx, (System.Object) mrl); decSpec.ecopts.setTileDef(tileIdx, (System.Object) ecOptions); decSpec.cts.setTileDef(tileIdx, (System.Object) ms.sgcod_mct); decSpec.nls.setTileDef(tileIdx, (System.Object) ms.sgcod_nl); decSpec.pos.setTileDef(tileIdx, (System.Object) ms.sgcod_po); } } /// Reads the COC marker segment and realigns the codestream where the next /// marker should be found. /// /// /// The encoder header stream. /// /// /// Flag indicating whether or not this marker segment is read /// from the main header. /// /// /// The index of the current tile /// /// /// Tile-part index /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readCOC(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int tpIdx) { int cComp; // current component SynWTFilter[] hfilters, vfilters; //int tmp, l; int ecOptions; System.Int32[] cblk; System.String errMsg; HeaderInfo.COC ms = hi.NewCOC; // Lcoc (marker length) ms.lcoc = ehs.ReadUInt16(); // Ccoc if (nComp < 257) { cComp = ms.ccoc = ehs.ReadByte(); } else { cComp = ms.ccoc = ehs.ReadUInt16(); } if (cComp >= nComp) { throw new CorruptedCodestreamException("Invalid component index " + "in QCC marker"); } // Scoc (block style) int cstyle = ms.scoc = ehs.ReadByte(); if ((cstyle & CSJ2K.j2k.codestream.Markers.SCOX_PRECINCT_PARTITION) != 0) { precinctPartitionIsUsed = true; // Remove flag cstyle &= ~ (CSJ2K.j2k.codestream.Markers.SCOX_PRECINCT_PARTITION); } else { precinctPartitionIsUsed = false; } // SPcoc // decomposition levels int mrl = ms.spcoc_ndl = ehs.ReadByte(); // Read the code-blocks dimensions cblk = new System.Int32[2]; ms.spcoc_cw = ehs.ReadByte(); cblk[0] = (System.Int32) (1 << (ms.spcoc_cw + 2)); if (cblk[0] < CSJ2K.j2k.entropy.StdEntropyCoderOptions.MIN_CB_DIM || cblk[0] > CSJ2K.j2k.entropy.StdEntropyCoderOptions.MAX_CB_DIM) { errMsg = "Non-valid code-block width in SPcod field, " + "COC marker"; throw new CorruptedCodestreamException(errMsg); } ms.spcoc_ch = ehs.ReadByte(); cblk[1] = (System.Int32) (1 << (ms.spcoc_ch + 2)); if (cblk[1] < CSJ2K.j2k.entropy.StdEntropyCoderOptions.MIN_CB_DIM || cblk[1] > CSJ2K.j2k.entropy.StdEntropyCoderOptions.MAX_CB_DIM) { errMsg = "Non-valid code-block height in SPcod field, " + "COC marker"; throw new CorruptedCodestreamException(errMsg); } if ((cblk[0] * cblk[1]) > CSJ2K.j2k.entropy.StdEntropyCoderOptions.MAX_CB_AREA) { errMsg = "Non-valid code-block area in SPcod field, " + "COC marker"; throw new CorruptedCodestreamException(errMsg); } if (mainh) { decSpec.cblks.setCompDef(cComp, (System.Object) (cblk)); } else { decSpec.cblks.setTileCompVal(tileIdx, cComp, (System.Object) (cblk)); } // Read entropy block mode options // NOTE: currently OPT_SEG_SYMBOLS is not included here ecOptions = ms.spcoc_cs = ehs.ReadByte(); if ((ecOptions & ~ (CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS)) != 0) { throw new CorruptedCodestreamException("Unknown \"code-block " + "context\" in SPcoc field, " + "COC marker: 0x" + System.Convert.ToString(ecOptions, 16)); } // Read wavelet filter for tile or image hfilters = new SynWTFilter[1]; vfilters = new SynWTFilter[1]; hfilters[0] = readFilter(ehs, ms.spcoc_t); vfilters[0] = hfilters[0]; // Fill the filter spec // If this is the main header, set the default value, if it is the // tile header, set default for this tile SynWTFilter[][] hvfilters = new SynWTFilter[2][]; hvfilters[0] = hfilters; hvfilters[1] = vfilters; // Get precinct partition sizes System.Collections.ArrayList[] v = new System.Collections.ArrayList[2]; v[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); v[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); int val = CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE; if (!precinctPartitionIsUsed) { System.Int32 w, h; w = (System.Int32) (1 << (val & 0x000F)); v[0].Add(w); h = (System.Int32) (1 << (((val & 0x00F0) >> 4))); v[1].Add(h); } else { ms.spcoc_ps = new int[mrl + 1]; for (int rl = mrl; rl >= 0; rl--) { System.Int32 w, h; val = ms.spcoc_ps[rl] = ehs.ReadByte(); w = (System.Int32) (1 << (val & 0x000F)); v[0].Insert(0, w); h = (System.Int32) (1 << (((val & 0x00F0) >> 4))); v[1].Insert(0, h); } } if (mainh) { decSpec.pss.setCompDef(cComp, v); } else { decSpec.pss.setTileCompVal(tileIdx, cComp, v); } precinctPartitionIsUsed = true; // Check marker length checkMarkerLength(ehs, "COD marker"); if (mainh) { hi.cocValue["main_c" + cComp] = ms; decSpec.wfs.setCompDef(cComp, hvfilters); decSpec.dls.setCompDef(cComp, (System.Object) mrl); decSpec.ecopts.setCompDef(cComp, (System.Object) ecOptions); } else { hi.cocValue["t" + tileIdx + "_c" + cComp] = ms; decSpec.wfs.setTileCompVal(tileIdx, cComp, hvfilters); decSpec.dls.setTileCompVal(tileIdx, cComp, (System.Object) mrl); decSpec.ecopts.setTileCompVal(tileIdx, cComp, (System.Object) ecOptions); } } /// Reads the POC marker segment and realigns the codestream where the next /// marker should be found. /// /// /// The encoder header stream. /// /// /// Flag indicating whether or not this marker segment is read /// from the main header. /// /// /// The index of the current tile /// /// /// Tile-part index /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readPOC(System.IO.BinaryReader ehs, bool mainh, int t, int tpIdx) { bool useShort = (nComp >= 256)?true:false; int tmp; int nOldChg = 0; HeaderInfo.POC ms; if (mainh || hi.pocValue["t" + t] == null) { ms = hi.NewPOC; } else { ms = (HeaderInfo.POC) hi.pocValue["t" + t]; nOldChg = ms.rspoc.Length; } // Lpoc ms.lpoc = ehs.ReadUInt16(); // Compute the number of new progression changes // newChg = (lpoc - Lpoc(2)) / (RSpoc(1) + CSpoc(2) + // LYEpoc(2) + REpoc(1) + CEpoc(2) + Ppoc (1) ) int newChg = (ms.lpoc - 2) / (5 + (useShort?4:2)); int ntotChg = nOldChg + newChg; int[][] change; if (nOldChg != 0) { // Creates new arrays int[][] tmpArray = new int[ntotChg][]; for (int i = 0; i < ntotChg; i++) { tmpArray[i] = new int[6]; } change = tmpArray; int[] tmprspoc = new int[ntotChg]; int[] tmpcspoc = new int[ntotChg]; int[] tmplyepoc = new int[ntotChg]; int[] tmprepoc = new int[ntotChg]; int[] tmpcepoc = new int[ntotChg]; int[] tmpppoc = new int[ntotChg]; // Copy old values int[][] prevChg = (int[][]) decSpec.pcs.getTileDef(t); for (int chg = 0; chg < nOldChg; chg++) { change[chg] = prevChg[chg]; tmprspoc[chg] = ms.rspoc[chg]; tmpcspoc[chg] = ms.cspoc[chg]; tmplyepoc[chg] = ms.lyepoc[chg]; tmprepoc[chg] = ms.repoc[chg]; tmpcepoc[chg] = ms.cepoc[chg]; tmpppoc[chg] = ms.ppoc[chg]; } ms.rspoc = tmprspoc; ms.cspoc = tmpcspoc; ms.lyepoc = tmplyepoc; ms.repoc = tmprepoc; ms.cepoc = tmpcepoc; ms.ppoc = tmpppoc; } else { int[][] tmpArray2 = new int[newChg][]; for (int i2 = 0; i2 < newChg; i2++) { tmpArray2[i2] = new int[6]; } change = tmpArray2; ms.rspoc = new int[newChg]; ms.cspoc = new int[newChg]; ms.lyepoc = new int[newChg]; ms.repoc = new int[newChg]; ms.cepoc = new int[newChg]; ms.ppoc = new int[newChg]; } for (int chg = nOldChg; chg < ntotChg; chg++) { // RSpoc change[chg][0] = ms.rspoc[chg] = ehs.ReadByte(); // CSpoc if (useShort) { change[chg][1] = ms.cspoc[chg] = ehs.ReadUInt16(); } else { change[chg][1] = ms.cspoc[chg] = ehs.ReadByte(); } // LYEpoc change[chg][2] = ms.lyepoc[chg] = ehs.ReadUInt16(); if (change[chg][2] < 1) { throw new CorruptedCodestreamException("LYEpoc value must be greater than 1 in POC marker " + "segment of tile " + t + ", tile-part " + tpIdx); } // REpoc change[chg][3] = ms.repoc[chg] = ehs.ReadByte(); if (change[chg][3] <= change[chg][0]) { throw new CorruptedCodestreamException("REpoc value must be greater than RSpoc in POC marker " + "segment of tile " + t + ", tile-part " + tpIdx); } // CEpoc if (useShort) { change[chg][4] = ms.cepoc[chg] = ehs.ReadUInt16(); } else { tmp = ms.cepoc[chg] = ehs.ReadByte(); if (tmp == 0) { change[chg][4] = 0; } else { change[chg][4] = tmp; } } if (change[chg][4] <= change[chg][1]) { throw new CorruptedCodestreamException("CEpoc value must be greater than CSpoc in POC marker " + "segment of tile " + t + ", tile-part " + tpIdx); } // Ppoc change[chg][5] = ms.ppoc[chg] = ehs.ReadByte(); } // Check marker length checkMarkerLength(ehs, "POC marker"); // Register specifications if (mainh) { hi.pocValue["main"] = ms; decSpec.pcs.setDefault(change); } else { hi.pocValue["t" + t] = ms; decSpec.pcs.setTileDef(t, change); } } /// Reads TLM marker segment and realigns the codestream where the next /// marker should be found. Informations stored in these fields are /// currently NOT taken into account. /// /// /// The encoder header stream. /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readTLM(System.IO.BinaryReader ehs) { int length; length = ehs.ReadUInt16(); //Ignore all informations contained System.IO.BinaryReader temp_BinaryReader; System.Int64 temp_Int64; temp_BinaryReader = ehs; temp_Int64 = temp_BinaryReader.BaseStream.Position; temp_Int64 = temp_BinaryReader.BaseStream.Seek(length - 2, System.IO.SeekOrigin.Current) - temp_Int64; // CONVERSION PROBLEM? int generatedAux = (int)temp_Int64; FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Skipping unsupported TLM marker"); } /// Reads PLM marker segment and realigns the codestream where the next /// marker should be found. Informations stored in these fields are /// currently not taken into account. /// /// /// The encoder header stream. /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readPLM(System.IO.BinaryReader ehs) { int length; length = ehs.ReadUInt16(); //Ignore all informations contained System.IO.BinaryReader temp_BinaryReader; System.Int64 temp_Int64; temp_BinaryReader = ehs; temp_Int64 = temp_BinaryReader.BaseStream.Position; temp_Int64 = temp_BinaryReader.BaseStream.Seek(length - 2, System.IO.SeekOrigin.Current) - temp_Int64; // CONVERSION PROBLEM? int generatedAux = (int)temp_Int64; FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Skipping unsupported PLM marker"); } /// Reads the PLT fields and realigns the codestream where the next marker /// should be found. Informations stored in these fields are currently NOT /// taken into account. /// /// /// The encoder header stream. /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readPLTFields(System.IO.BinaryReader ehs) { int length; length = ehs.ReadUInt16(); //Ignore all informations contained System.IO.BinaryReader temp_BinaryReader; System.Int64 temp_Int64; temp_BinaryReader = ehs; temp_Int64 = temp_BinaryReader.BaseStream.Position; temp_Int64 = temp_BinaryReader.BaseStream.Seek(length - 2, System.IO.SeekOrigin.Current) - temp_Int64; // CONVERSION PROBLEM? int generatedAux = (int)temp_Int64; FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Skipping unsupported PLT marker"); } /// Reads the RGN marker segment of the codestream header. /// ///

May be used in tile or main header. If used in main header, it /// refers to the maxshift value of a component in all tiles. When used in /// tile header, only the particular tile-component is affected.

/// ///
/// The encoder header stream. /// /// /// Flag indicating whether or not this marker segment is read /// from the main header. /// /// /// The index of the current tile /// /// /// Tile-part index /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readRGN(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int tpIdx) { int comp; // ROI component //int i; // loop variable //int tempComp; // Component for HeaderInfo.RGN ms = hi.NewRGN; // Lrgn (marker length) ms.lrgn = ehs.ReadUInt16(); // Read component ms.crgn = comp = (nComp < 257)?ehs.ReadByte():ehs.ReadUInt16(); if (comp >= nComp) { throw new CorruptedCodestreamException("Invalid component " + "index in RGN marker" + comp); } // Read type of RGN.(Srgn) ms.srgn = ehs.ReadByte(); // Check that we can handle it. if (ms.srgn != CSJ2K.j2k.codestream.Markers.SRGN_IMPLICIT) throw new CorruptedCodestreamException("Unknown or unsupported " + "Srgn parameter in ROI " + "marker"); if (decSpec.rois == null) { // No maxshift spec defined // Create needed ModuleSpec decSpec.rois = new MaxShiftSpec(nTiles, nComp, ModuleSpec.SPEC_TYPE_TILE_COMP); } // SPrgn ms.sprgn = ehs.ReadByte(); if (mainh) { hi.rgnValue["main_c" + comp] = ms; decSpec.rois.setCompDef(comp, (System.Object) ms.sprgn); } else { hi.rgnValue["t" + tileIdx + "_c" + comp] = ms; decSpec.rois.setTileCompVal(tileIdx, comp, (System.Object) ms.sprgn); } // Check marker length checkMarkerLength(ehs, "RGN marker"); } /// Reads the PPM marker segment of the main header. /// /// /// The encoder header stream. /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readPPM(System.IO.BinaryReader ehs) { int curMarkSegLen; int indx; // i, len, off removed int remSegLen; //byte[] b; // If first time readPPM method is called allocate arrays for packed // packet data if (pPMMarkerData == null) { pPMMarkerData = new byte[nPPMMarkSeg][]; tileOfTileParts = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); decSpec.pphs.setDefault((System.Object) true); } // Lppm (marker length) curMarkSegLen = ehs.ReadUInt16(); remSegLen = curMarkSegLen - 3; // Zppm (index of PPM marker) indx = ehs.ReadByte(); // Read Nppm and Ippm data pPMMarkerData[indx] = new byte[remSegLen]; ehs.BaseStream.Read(pPMMarkerData[indx], 0, remSegLen); //SupportClass.ReadInput(ehs.BaseStream, pPMMarkerData[indx], 0, remSegLen); // Check marker length checkMarkerLength(ehs, "PPM marker"); } /// Reads the PPT marker segment of the main header. /// /// /// The encoder header stream. /// /// /// The tile to which the current tile part belongs /// /// /// Tile-part index /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" private void readPPT(System.IO.BinaryReader ehs, int tile, int tpIdx) { int curMarkSegLen; int indx; // len = 0; removed byte[] temp; if (tilePartPkdPktHeaders == null) { tilePartPkdPktHeaders = new byte[nTiles][][][]; } if (tilePartPkdPktHeaders[tile] == null) { tilePartPkdPktHeaders[tile] = new byte[nTileParts[tile]][][]; } if (tilePartPkdPktHeaders[tile][tpIdx] == null) { tilePartPkdPktHeaders[tile][tpIdx] = new byte[nPPTMarkSeg[tile][tpIdx]][]; } // Lppt (marker length) curMarkSegLen = ehs.ReadUInt16(); // Zppt (index of PPT marker) indx = ehs.ReadByte(); // Ippt (packed packet headers) temp = new byte[curMarkSegLen - 3]; ehs.BaseStream.Read(temp, 0, temp.Length); //SupportClass.ReadInput(ehs.BaseStream, temp, 0, temp.Length); tilePartPkdPktHeaders[tile][tpIdx][indx] = temp; // Check marker length checkMarkerLength(ehs, "PPT marker"); decSpec.pphs.setTileDef(tile, (System.Object) true); } /// This method extract a marker segment from the main header and stores it /// into a byte buffer for the second pass. The marker segment is first /// identified. Then its flag is activated. Finally, its content is /// buffered into a byte array stored in an hashTable. /// ///

If the marker is not recognized, it prints a warning and skips it /// according to its length.

/// ///

SIZ marker segment shall be the first encountered marker segment.

/// ///
/// The marker segment to process /// /// /// The encoded header stream /// /// private void extractMainMarkSeg(short marker, RandomAccessIO ehs) { if (nfMarkSeg == 0) { // First non-delimiting marker of the header // JPEG 2000 part 1 specify that it must be SIZ if (marker != CSJ2K.j2k.codestream.Markers.SIZ) { throw new CorruptedCodestreamException("First marker after " + "SOC " + "must be SIZ " + System.Convert.ToString(marker, 16)); } } System.String htKey = ""; // Name used as a key for the hash-table if (ht == null) { ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); } switch (marker) { case CSJ2K.j2k.codestream.Markers.SIZ: if ((nfMarkSeg & SIZ_FOUND) != 0) { throw new CorruptedCodestreamException("More than one SIZ marker " + "segment found in main " + "header"); } nfMarkSeg |= SIZ_FOUND; htKey = "SIZ"; break; case CSJ2K.j2k.codestream.Markers.SOD: throw new CorruptedCodestreamException("SOD found in main header"); case CSJ2K.j2k.codestream.Markers.EOC: throw new CorruptedCodestreamException("EOC found in main header"); case CSJ2K.j2k.codestream.Markers.SOT: if ((nfMarkSeg & SOT_FOUND) != 0) { throw new CorruptedCodestreamException("More than one SOT " + "marker " + "found right after " + "main " + "or tile header"); } nfMarkSeg |= SOT_FOUND; return ; case CSJ2K.j2k.codestream.Markers.COD: if ((nfMarkSeg & COD_FOUND) != 0) { throw new CorruptedCodestreamException("More than one COD " + "marker " + "found in main header"); } nfMarkSeg |= COD_FOUND; htKey = "COD"; break; case CSJ2K.j2k.codestream.Markers.COC: nfMarkSeg |= COC_FOUND; htKey = "COC" + (nCOCMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.QCD: if ((nfMarkSeg & QCD_FOUND) != 0) { throw new CorruptedCodestreamException("More than one QCD " + "marker " + "found in main header"); } nfMarkSeg |= QCD_FOUND; htKey = "QCD"; break; case CSJ2K.j2k.codestream.Markers.QCC: nfMarkSeg |= QCC_FOUND; htKey = "QCC" + (nQCCMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.RGN: nfMarkSeg |= RGN_FOUND; htKey = "RGN" + (nRGNMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.COM: nfMarkSeg |= COM_FOUND; htKey = "COM" + (nCOMMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.CRG: if ((nfMarkSeg & CRG_FOUND) != 0) { throw new CorruptedCodestreamException("More than one CRG " + "marker " + "found in main header"); } nfMarkSeg |= CRG_FOUND; htKey = "CRG"; break; case CSJ2K.j2k.codestream.Markers.PPM: nfMarkSeg |= PPM_FOUND; htKey = "PPM" + (nPPMMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.TLM: if ((nfMarkSeg & TLM_FOUND) != 0) { throw new CorruptedCodestreamException("More than one TLM " + "marker " + "found in main header"); } nfMarkSeg |= TLM_FOUND; break; case CSJ2K.j2k.codestream.Markers.PLM: if ((nfMarkSeg & PLM_FOUND) != 0) { throw new CorruptedCodestreamException("More than one PLM " + "marker " + "found in main header"); } FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "PLM marker segment found but " + "not used by by JJ2000 decoder."); nfMarkSeg |= PLM_FOUND; htKey = "PLM"; break; case CSJ2K.j2k.codestream.Markers.POC: if ((nfMarkSeg & POC_FOUND) != 0) { throw new CorruptedCodestreamException("More than one POC " + "marker segment found " + "in main header"); } nfMarkSeg |= POC_FOUND; htKey = "POC"; break; case CSJ2K.j2k.codestream.Markers.PLT: throw new CorruptedCodestreamException("PLT found in main header"); case CSJ2K.j2k.codestream.Markers.PPT: throw new CorruptedCodestreamException("PPT found in main header"); default: htKey = "UNKNOWN"; FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Non recognized marker segment (0x" + System.Convert.ToString(marker, 16) + ") in main header!"); break; } if (marker < unchecked((short)0xffffff30) || marker > unchecked((short)0xffffff3f)) { // Read marker segment length and create corresponding byte buffer int markSegLen = ehs.readUnsignedShort(); byte[] buf = new byte[markSegLen]; // Copy data (after re-insertion of the marker segment length); buf[0] = (byte) ((markSegLen >> 8) & 0xFF); buf[1] = (byte) (markSegLen & 0xFF); ehs.readFully(buf, 2, markSegLen - 2); if (!htKey.Equals("UNKNOWN")) { // Store array in hashTable ht[htKey] = buf; } } } /// This method extracts a marker segment in a tile-part header and stores /// it into a byte buffer for the second pass. The marker is first /// recognized, then its flag is activated and, finally, its content is /// buffered in an element of byte arrays accessible thanks to a hashTable. /// If a marker segment is not recognized, it prints a warning and skip it /// according to its length. /// /// /// The marker to process /// /// /// The encoded header stream /// /// /// The index of the current tile /// /// /// The index of the current tile part /// /// public virtual void extractTilePartMarkSeg(short marker, RandomAccessIO ehs, int tileIdx, int tilePartIdx) { System.String htKey = ""; // Name used as a hash-table key if (ht == null) { ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); } switch (marker) { case CSJ2K.j2k.codestream.Markers.SOT: throw new CorruptedCodestreamException("Second SOT marker " + "segment found in tile-" + "part header"); case CSJ2K.j2k.codestream.Markers.SIZ: throw new CorruptedCodestreamException("SIZ found in tile-part" + " header"); case CSJ2K.j2k.codestream.Markers.EOC: throw new CorruptedCodestreamException("EOC found in tile-part" + " header"); case CSJ2K.j2k.codestream.Markers.TLM: throw new CorruptedCodestreamException("TLM found in tile-part" + " header"); case CSJ2K.j2k.codestream.Markers.PLM: throw new CorruptedCodestreamException("PLM found in tile-part" + " header"); case CSJ2K.j2k.codestream.Markers.PPM: throw new CorruptedCodestreamException("PPM found in tile-part" + " header"); case CSJ2K.j2k.codestream.Markers.COD: if ((nfMarkSeg & COD_FOUND) != 0) { throw new CorruptedCodestreamException("More than one COD " + "marker " + "found in tile-part" + " header"); } nfMarkSeg |= COD_FOUND; htKey = "COD"; break; case CSJ2K.j2k.codestream.Markers.COC: nfMarkSeg |= COC_FOUND; htKey = "COC" + (nCOCMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.QCD: if ((nfMarkSeg & QCD_FOUND) != 0) { throw new CorruptedCodestreamException("More than one QCD " + "marker " + "found in tile-part" + " header"); } nfMarkSeg |= QCD_FOUND; htKey = "QCD"; break; case CSJ2K.j2k.codestream.Markers.QCC: nfMarkSeg |= QCC_FOUND; htKey = "QCC" + (nQCCMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.RGN: nfMarkSeg |= RGN_FOUND; htKey = "RGN" + (nRGNMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.COM: nfMarkSeg |= COM_FOUND; htKey = "COM" + (nCOMMarkSeg++); break; case CSJ2K.j2k.codestream.Markers.CRG: throw new CorruptedCodestreamException("CRG marker found in " + "tile-part header"); case CSJ2K.j2k.codestream.Markers.PPT: nfMarkSeg |= PPT_FOUND; if (nPPTMarkSeg == null) { nPPTMarkSeg = new int[nTiles][]; } if (nPPTMarkSeg[tileIdx] == null) { nPPTMarkSeg[tileIdx] = new int[nTileParts[tileIdx]]; } htKey = "PPT" + (nPPTMarkSeg[tileIdx][tilePartIdx]++); break; case CSJ2K.j2k.codestream.Markers.SOD: nfMarkSeg |= SOD_FOUND; return ; case CSJ2K.j2k.codestream.Markers.POC: if ((nfMarkSeg & POC_FOUND) != 0) throw new CorruptedCodestreamException("More than one POC " + "marker segment found " + "in tile-part" + " header"); nfMarkSeg |= POC_FOUND; htKey = "POC"; break; case CSJ2K.j2k.codestream.Markers.PLT: if ((nfMarkSeg & PLM_FOUND) != 0) { throw new CorruptedCodestreamException("PLT marker found even" + "though PLM marker " + "found in main header"); } FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "PLT marker segment found but " + "not used by JJ2000 decoder."); htKey = "UNKNOWN"; break; default: htKey = "UNKNOWN"; FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Non recognized marker segment (0x" + System.Convert.ToString(marker, 16) + ") in tile-part header" + " of tile " + tileIdx + " !"); break; } // Read marker segment length and create corresponding byte buffer int markSegLen = ehs.readUnsignedShort(); byte[] buf = new byte[markSegLen]; // Copy data (after re-insertion of marker segment length); buf[0] = (byte) ((markSegLen >> 8) & 0xFF); buf[1] = (byte) (markSegLen & 0xFF); ehs.readFully(buf, 2, markSegLen - 2); if (!htKey.Equals("UNKNOWN")) { // Store array in hashTable ht[htKey] = buf; } } /// Retrieves and reads all marker segments found in the main header during /// the first pass. /// /// private void readFoundMainMarkSeg() { //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" //System.IO.BinaryReader dis; System.IO.MemoryStream bais; // SIZ marker segment if ((nfMarkSeg & SIZ_FOUND) != 0) { bais = new System.IO.MemoryStream((byte[])ht["SIZ"]); readSIZ(new CSJ2K.Util.EndianBinaryReader(bais, true)); bais.Dispose(); } // COM marker segments if ((nfMarkSeg & COM_FOUND) != 0) { for (int i = 0; i < nCOMMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["COM" + i]); readCOM(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, i); bais.Dispose(); } } // CRG marker segment if ((nfMarkSeg & CRG_FOUND) != 0) { bais = new System.IO.MemoryStream((byte[])ht["CRG"]); readCRG(new CSJ2K.Util.EndianBinaryReader(bais, true)); bais.Dispose(); } // COD marker segment if ((nfMarkSeg & COD_FOUND) != 0) { bais = new System.IO.MemoryStream((byte[])ht["COD"]); readCOD(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); bais.Dispose(); } // COC marker segments if ((nfMarkSeg & COC_FOUND) != 0) { for (int i = 0; i < nCOCMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["COC" + i]); readCOC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); bais.Dispose(); } } // RGN marker segment if ((nfMarkSeg & RGN_FOUND) != 0) { for (int i = 0; i < nRGNMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["RGN" + i]); readRGN(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); bais.Dispose(); } } // QCD marker segment if ((nfMarkSeg & QCD_FOUND) != 0) { bais = new System.IO.MemoryStream((byte[])ht["QCD"]); readQCD(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); bais.Dispose(); } // QCC marker segments if ((nfMarkSeg & QCC_FOUND) != 0) { for (int i = 0; i < nQCCMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["QCC" + i]); readQCC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); bais.Dispose(); } } // POC marker segment if ((nfMarkSeg & POC_FOUND) != 0) { bais = new System.IO.MemoryStream((byte[])ht["POC"]); readPOC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); bais.Dispose(); } // PPM marker segments if ((nfMarkSeg & PPM_FOUND) != 0) { for (int i = 0; i < nPPMMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["PPM" + i]); readPPM(new CSJ2K.Util.EndianBinaryReader(bais)); bais.Dispose(); } } // Reset the hashtable ht = null; } /// Retrieves and reads all marker segments previously found in the /// tile-part header. /// /// /// The index of the current tile /// /// /// Index of the current tile-part /// /// public virtual void readFoundTilePartMarkSeg(int tileIdx, int tpIdx) { //UPGRADE_TODO: Class 'java.io.DataInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataInputStream'" //CSJ2K.EndianBinaryReader dis; System.IO.MemoryStream bais; // COD marker segment if ((nfMarkSeg & COD_FOUND) != 0) { bais = new System.IO.MemoryStream((byte[])ht["COD"]); readCOD(new CSJ2K.Util.EndianBinaryReader(bais, true), false, tileIdx, tpIdx); } // COC marker segments if ((nfMarkSeg & COC_FOUND) != 0) { for (int i = 0; i < nCOCMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["COC" + i]); readCOC(new CSJ2K.Util.EndianBinaryReader(bais, true), false, tileIdx, tpIdx); } } // RGN marker segment if ((nfMarkSeg & RGN_FOUND) != 0) { for (int i = 0; i < nRGNMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["RGN" + i]); readRGN(new CSJ2K.Util.EndianBinaryReader(bais, true), false, tileIdx, tpIdx); } } // QCD marker segment if ((nfMarkSeg & QCD_FOUND) != 0) { bais = new System.IO.MemoryStream((byte[])ht["QCD"]); readQCD(new CSJ2K.Util.EndianBinaryReader(bais, true), false, tileIdx, tpIdx); } // QCC marker segments if ((nfMarkSeg & QCC_FOUND) != 0) { for (int i = 0; i < nQCCMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["QCC" + i]); readQCC(new CSJ2K.Util.EndianBinaryReader(bais, true), false, tileIdx, tpIdx); } } // POC marker segment if ((nfMarkSeg & POC_FOUND) != 0) { bais = new System.IO.MemoryStream((byte[])ht["POC"]); readPOC(new CSJ2K.Util.EndianBinaryReader(bais, true), false, tileIdx, tpIdx); } // COM marker segments if ((nfMarkSeg & COM_FOUND) != 0) { for (int i = 0; i < nCOMMarkSeg; i++) { bais = new System.IO.MemoryStream((byte[])ht["COM" + i]); readCOM(new CSJ2K.Util.EndianBinaryReader(bais, true), false, tileIdx, i); } } // PPT marker segments if ((nfMarkSeg & PPT_FOUND) != 0) { for (int i = 0; i < nPPTMarkSeg[tileIdx][tpIdx]; i++) { bais = new System.IO.MemoryStream((byte[])ht["PPT" + i]); readPPT(new CSJ2K.Util.EndianBinaryReader(bais, true), tileIdx, tpIdx); } } // Reset ht ht = null; } /// Creates a HeaderDecoder instance and read in two passes the main header /// of the codestream. The first and last marker segments shall be /// respectively SOC and SOT. /// /// /// The encoded header stream where marker segments are /// extracted. /// /// /// The ParameterList object of the decoder /// /// /// The HeaderInfo holding information found in marker segments /// /// /// If an I/O error occurs while reading from the /// encoded header stream. /// /// If the end of the encoded header stream is /// reached before getting all the data. /// /// If invalid data is found in the /// codestream main header. /// /// public HeaderDecoder(RandomAccessIO ehs, ParameterList pl, HeaderInfo hi) { this.hi = hi; // CONVERSION PROBLEM? //this.verbose = verbose; pl.checkList(OPT_PREFIX, ParameterList.toNameArray(pinfo)); mainHeadOff = ehs.Pos; if (((short) ehs.readShort()) != CSJ2K.j2k.codestream.Markers.SOC) { throw new CorruptedCodestreamException("SOC marker segment not " + " found at the " + "beginning of the " + "codestream."); } // First Pass: Decode and store main header information until the SOT // marker segment is found nfMarkSeg = 0; do { extractMainMarkSeg(ehs.readShort(), ehs); } while ((nfMarkSeg & SOT_FOUND) == 0); //Stop when SOT is found ehs.seek(ehs.Pos - 2); // Realign codestream on SOT marker // Second pass: Read each marker segment previously found readFoundMainMarkSeg(); } /// Creates and returns the entropy decoder corresponding to the /// information read from the codestream header and with the special /// additional parameters from the parameter list. /// /// /// The bit stream reader agent where to get code-block data /// from. /// /// /// The parameter list containing parameters applicable to the /// entropy decoder (other parameters can also be present). /// /// /// The entropy decoder /// /// public virtual EntropyDecoder createEntropyDecoder(CodedCBlkDataSrcDec src, ParameterList pl) { bool doer; bool verber; int mMax; // Check parameters pl.checkList(EntropyDecoder.OPT_PREFIX, ParameterList.toNameArray(EntropyDecoder.ParameterInfo)); // Get error detection option doer = pl.getBooleanParameter("Cer"); // Get verbose error detection option verber = pl.getBooleanParameter("Cverber"); // Get maximum number of bit planes from m quit condition mMax = pl.getIntParameter("m_quit"); return new StdEntropyDecoder(src, decSpec, doer, verber, mMax); } /// Creates and returns the EnumeratedColorSpaceMapper /// corresponding to the information read from the JP2 image file /// via the ColorSpace parameter. /// /// /// The bit stream reader agent where to get code-block /// data from. /// /// provides color space information from the image file /// /// /// The color space mapping object /// /// image access exception /// /// if image contains a bad icc profile /// /// if image contains a bad colorspace box /// /// public virtual BlkImgDataSrc createColorSpaceMapper(BlkImgDataSrc src, CSJ2K.Color.ColorSpace csMap) { return ColorSpaceMapper.createInstance(src, csMap); } /// Creates and returns the ChannelDefinitonMapper which maps the /// input channels to the channel definition for the appropriate /// colorspace. /// /// /// The bit stream reader agent where to get code-block /// data from. /// /// provides color space information from the image file /// /// /// The channel definition mapping object /// /// image access exception /// /// if image contains a bad colorspace box /// /// public virtual BlkImgDataSrc createChannelDefinitionMapper(BlkImgDataSrc src, CSJ2K.Color.ColorSpace csMap) { return ChannelDefinitionMapper.createInstance(src, csMap); } /// Creates and returns the PalettizedColorSpaceMapper which uses /// the input samples as indicies into a sample palette to /// construct the output. /// /// /// The bit stream reader agent where to get code-block /// data from. /// /// provides color space information from the image file /// /// /// a PalettizedColorSpaceMapper instance /// /// image access exception /// /// if image contains a bad colorspace box /// /// public virtual BlkImgDataSrc createPalettizedColorSpaceMapper(BlkImgDataSrc src, CSJ2K.Color.ColorSpace csMap) { return PalettizedColorSpaceMapper.createInstance(src, csMap); } /// Creates and returns the Resampler which converts the input /// source to one in which all channels have the same number of /// samples. This is required for colorspace conversions. /// /// /// The bit stream reader agent where to get code-block /// data from. /// /// provides color space information from the image file /// /// /// The resampled BlkImgDataSrc /// /// image access exception /// /// if image contains a bad colorspace box /// /// public virtual BlkImgDataSrc createResampler(BlkImgDataSrc src, CSJ2K.Color.ColorSpace csMap) { return Resampler.createInstance(src, csMap); } /// Creates and returns the ROIDeScaler corresponding to the information /// read from the codestream header and with the special additional /// parameters from the parameter list. /// /// /// The bit stream reader agent where to get code-block data /// from. /// /// /// The parameter list containing parameters applicable to the /// entropy decoder (other parameters can also be present). /// /// /// The DecoderSpecs instance after any image manipulation. /// /// /// The ROI descaler. /// /// public virtual ROIDeScaler createROIDeScaler(CBlkQuantDataSrcDec src, ParameterList pl, DecoderSpecs decSpec2) { return ROIDeScaler.createInstance(src, pl, decSpec2); } /// Method that resets members indicating which markers have already been /// found /// /// public virtual void resetHeaderMarkers() { // The found status of PLM remains since only PLM OR PLT allowed // Same goes for PPM and PPT nfMarkSeg = nfMarkSeg & (PLM_FOUND | PPM_FOUND); nCOCMarkSeg = 0; nQCCMarkSeg = 0; nCOMMarkSeg = 0; nRGNMarkSeg = 0; } /// Print information about the current header. /// /// /// Information in a String /// /// public override System.String ToString() { return hdStr; } /// Return the packed packet headers for a given tile. /// /// /// An input stream containing the packed packet headers for a /// particular tile /// /// /// If an I/O error occurs while reading from the /// encoder header stream /// /// public virtual System.IO.MemoryStream getPackedPktHead(int tile) { if (pkdPktHeaders == null) { int i, t; pkdPktHeaders = new System.IO.MemoryStream[nTiles]; for (i = nTiles - 1; i >= 0; i--) { pkdPktHeaders[i] = new System.IO.MemoryStream(); } if (nPPMMarkSeg != 0) { // If this is first time packed packet headers are requested, // create packed packet headers from Nppm and Ippm fields int nppm; int nTileParts = tileOfTileParts.Count; byte[] temp; System.IO.MemoryStream pph; System.IO.MemoryStream allNppmIppm = new System.IO.MemoryStream(); // Concatenate all Nppm and Ippm fields for (i = 0; i < nPPMMarkSeg; i++) { byte[] temp_byteArray; temp_byteArray = pPMMarkerData[i]; allNppmIppm.Write(temp_byteArray, 0, temp_byteArray.Length); } pph = new System.IO.MemoryStream(allNppmIppm.ToArray()); // Read all packed packet headers and concatenate for each // tile part for (i = 0; i < nTileParts; i++) { t = ((System.Int32) tileOfTileParts[i]); // get Nppm value nppm = (pph.ReadByte() << 24) | (pph.ReadByte() << 16) | (pph.ReadByte() << 8) | (pph.ReadByte()); temp = new byte[nppm]; // get ippm field pph.Read(temp, 0, temp.Length); //SupportClass.ReadInput(pph, temp, 0, temp.Length); byte[] temp_byteArray2; temp_byteArray2 = temp; pkdPktHeaders[t].Write(temp_byteArray2, 0, temp_byteArray2.Length); } } else { int tp; // Write all packed packet headers to pkdPktHeaders for (t = nTiles - 1; t >= 0; t--) { for (tp = 0; tp < nTileParts[t]; tp++) { for (i = 0; i < nPPTMarkSeg[t][tp]; i++) { byte[] temp_byteArray3; temp_byteArray3 = tilePartPkdPktHeaders[t][tp][i]; pkdPktHeaders[t].Write(temp_byteArray3, 0, temp_byteArray3.Length); } } } } } return new System.IO.MemoryStream(pkdPktHeaders[tile].ToArray()); } } }