Example #1
0
		/// <summary> 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.
		/// 
		/// </summary>
		/// <param name="ehs">The encoded stream.
		/// 
		/// </param>
		/// <param name="mainh">Flag indicating whether or not this marker segment is read
		/// from the main header.
		/// 
		/// </param>
		/// <param name="tileIdx">The index of the current tile
		/// 
		/// </param>
		/// <param name="tpIdx">Tile-part index
		/// 
		/// </param>
		/// <exception cref="IOException">If an I/O error occurs while reading from the
		/// encoded header stream.
		/// 
		/// </exception>
		//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<<exp) might
						// overflow (the - is used to be able to represent 2**31)
						//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
						nStep[rl][j] = (- 1f - ((float) (tmp & 0x07ff)) / (1 << 11)) / (- 1 << exp[rl][j]);
					}
				} // end for rl
			} // end if (qType != SQCX_NO_QUANTIZATION)
			
			// Fill qsss, gbs
			if (mainh)
			{
				decSpec.qsss.setDefault(qParms);
				decSpec.gbs.setDefault((System.Object) guardBits);
			}
			else
			{
				decSpec.qsss.setTileDef(tileIdx, qParms);
				decSpec.gbs.setTileDef(tileIdx, (System.Object) guardBits);
			}
			
			// Check marker length
			checkMarkerLength(ehs, "QCD marker");
		}
		/// <summary> Changes the current tile, given the new indexes. An
		/// IllegalArgumentException is thrown if the indexes do not correspond to
		/// a valid tile.
		/// 
		/// </summary>
		/// <param name="x">The horizontal indexes the tile.
		/// 
		/// </param>
		/// <param name="y">The vertical indexes of the new tile.
		/// 
		/// </param>
		public override void  setTile(int x, int y)
		{
			
			int i; // counter
			// Check validity of tile indexes
			if (x < 0 || y < 0 || x >= ntX || y >= ntY)
			{
				throw new System.ArgumentException();
			}
			int t = (y * ntX + x);
			
			// Reset number of read bytes if needed
			if (t == 0)
			{
				anbytes = headLen;
				if (!isTruncMode)
				{
					anbytes += 2;
				}
				// Restore values of nBytes
				for (int tIdx = 0; tIdx < nt; tIdx++)
				{
					nBytes[tIdx] = baknBytes[tIdx];
				}
			}
			
			// Set the new current tile
			ctX = x;
			ctY = y;
			// Calculate tile relative points
			int ctox = (x == 0)?ax:px + x * ntW;
			int ctoy = (y == 0)?ay:py + y * ntH;
			for (i = nc - 1; i >= 0; i--)
			{
				culx[i] = (ctox + hd.getCompSubsX(i) - 1) / hd.getCompSubsX(i);
				culy[i] = (ctoy + hd.getCompSubsY(i) - 1) / hd.getCompSubsY(i);
				offX[i] = (px + x * ntW + hd.getCompSubsX(i) - 1) / hd.getCompSubsX(i);
				offY[i] = (py + y * ntH + hd.getCompSubsY(i) - 1) / hd.getCompSubsY(i);
			}
			
			// Initialize subband tree and number of resolution levels
			subbTrees = new SubbandSyn[nc];
			mdl = new int[nc];
			derived = new bool[nc];
			params_Renamed = new StdDequantizerParams[nc];
			gb = new int[nc];
			
			for (int c = 0; c < nc; c++)
			{
				derived[c] = decSpec.qts.isDerived(t, c);
				params_Renamed[c] = (StdDequantizerParams) decSpec.qsss.getTileCompVal(t, c);
				gb[c] = ((System.Int32) decSpec.gbs.getTileCompVal(t, c));
				mdl[c] = ((System.Int32) decSpec.dls.getTileCompVal(t, c));
				
				subbTrees[c] = new SubbandSyn(getTileCompWidth(t, c, mdl[c]), getTileCompHeight(t, c, mdl[c]), getResULX(c, mdl[c]), getResULY(c, mdl[c]), mdl[c], decSpec.wfs.getHFilters(t, c), decSpec.wfs.getVFilters(t, c));
				initSubbandsFields(c, subbTrees[c]);
			}
			
			// Read tile's packets
			try
			{
				readTilePkts(t);
			}
			catch (System.IO.IOException e)
			{
				SupportClass.WriteStackTrace(e, Console.Error);
				throw new System.ApplicationException("IO Error when reading tile " + x + " x " + y);
			}
		}
Example #3
0
        /// <summary> Returns the specified code-block in the current tile for the specified
        /// component (as a reference or copy).
        ///
        /// <p>The returned code-block may be progressive, which is indicated by
        /// the 'progressive' variable of the returned 'DataBlk'
        /// object. If a code-block is progressive it means that in a later request
        /// to this method for the same code-block it is possible to retrieve data
        /// which is a better approximation, since meanwhile more data to decode
        /// for the code-block could have been received. If the code-block is not
        /// progressive then later calls to this method for the same code-block
        /// will return the exact same data values.</p>
        ///
        /// <p>The data returned by this method can be the data in the internal
        /// buffer of this object, if any, and thus can not be modified by the
        /// caller. The 'offset' and 'scanw' of the returned data can be
        /// arbitrary. See the 'DataBlk' class.</p>
        ///
        /// </summary>
        /// <param name="c">The component for which to return the next code-block.
        ///
        /// </param>
        /// <param name="m">The vertical index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="n">The horizontal index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="sb">The subband in which the code-block to return is.
        ///
        /// </param>
        /// <param name="cblk">If non-null this object will be used to return the new
        /// code-block. If null a new one will be allocated and returned. If the
        /// "data" array of the object is non-null it will be reused, if possible,
        /// to return the data.
        ///
        /// </param>
        /// <returns> The next code-block in the current tile for component 'n', or
        /// null if all code-blocks for the current tile have been returned.
        ///
        /// </returns>
        /// <seealso cref="DataBlk">
        ///
        /// </seealso>
        public override DataBlk getInternCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
        {
            // This method is declared final since getNextCodeBlock() relies on
            // the actual implementation of this method.
            int   j, jmin, k;
            int   temp;
            float step;
            int   shiftBits;
            int   magBits;

            int[]   outiarr, inarr;
            float[] outfarr;
            int     w, h;
            bool    reversible = qts.isReversible(tIdx, c);
            bool    derived    = qts.isDerived(tIdx, c);
            StdDequantizerParams params_Renamed = (StdDequantizerParams)qsss.getTileCompVal(tIdx, c);
            int G = ((System.Int32)gbs.getTileCompVal(tIdx, c));

            outdtype = cblk.DataType;

            if (reversible && outdtype != DataBlk.TYPE_INT)
            {
                throw new System.ArgumentException("Reversible quantizations " + "must use int data");
            }

            // To get compiler happy
            outiarr = null;
            outfarr = null;
            inarr   = null;

            // Get source data and initialize output DataBlk object.
            switch (outdtype)
            {
            case DataBlk.TYPE_INT:
                // With int data we can use the same DataBlk object to get the
                // data from the source and return the dequantized data, and we
                // can also work "in place" (i.e. same buffer).
                cblk = src.getCodeBlock(c, m, n, sb, cblk);
                // Input and output arrays are the same
                outiarr = (int[])cblk.Data;
                break;

            case DataBlk.TYPE_FLOAT:
                // With float data we must use a different DataBlk objects to get
                // the data from the source and to return the dequantized data.
                inblk = (DataBlkInt)src.getInternCodeBlock(c, m, n, sb, inblk);
                inarr = inblk.DataInt;
                if (cblk == null)
                {
                    cblk = new DataBlkFloat();
                }
                // Copy the attributes of the CodeBlock object
                cblk.ulx         = inblk.ulx;
                cblk.uly         = inblk.uly;
                cblk.w           = inblk.w;
                cblk.h           = inblk.h;
                cblk.offset      = 0;
                cblk.scanw       = cblk.w;
                cblk.progressive = inblk.progressive;
                // Get output data array and check its size
                outfarr = (float[])cblk.Data;
                if (outfarr == null || outfarr.Length < cblk.w * cblk.h)
                {
                    outfarr   = new float[cblk.w * cblk.h];
                    cblk.Data = outfarr;
                }
                break;
            }

            magBits = sb.magbits;

            // Calculate quantization step and number of magnitude bits
            // depending on reversibility and derivedness and perform
            // inverse quantization
            if (reversible)
            {
                shiftBits = 31 - magBits;
                // For int data Inverse quantization happens "in-place". The input
                // array has an offset of 0 and scan width equal to the code-block
                // width.
                for (j = outiarr.Length - 1; j >= 0; j--)
                {
                    temp       = outiarr[j]; // input array is same as output one
                    outiarr[j] = (temp >= 0) ? (temp >> shiftBits) : -((temp & 0x7FFFFFFF) >> shiftBits);
                }
            }
            else
            {
                // Not reversible
                if (derived)
                {
                    // Max resolution level
                    int mrl = src.getSynSubbandTree(TileIdx, c).resLvl;
                    step = params_Renamed.nStep[0][0] * (1L << (rb[c] + sb.anGainExp + mrl - sb.level));
                }
                else
                {
                    step = params_Renamed.nStep[sb.resLvl][sb.sbandIdx] * (1L << (rb[c] + sb.anGainExp));
                }
                shiftBits = 31 - magBits;

                // Adjust step to the number of shiftBits
                step /= (1 << shiftBits);

                switch (outdtype)
                {
                case DataBlk.TYPE_INT:
                    // For int data Inverse quantization happens "in-place". The
                    // input array has an offset of 0 and scan width equal to the
                    // code-block width.
                    for (j = outiarr.Length - 1; j >= 0; j--)
                    {
                        temp = outiarr[j];     // input array is same as output one
                                               //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                        outiarr[j] = (int)(((float)((temp >= 0) ? temp : -(temp & 0x7FFFFFFF))) * step);
                    }
                    break;

                case DataBlk.TYPE_FLOAT:
                    // For float data the inverse quantization can not happen
                    // "in-place".
                    w = cblk.w;
                    h = cblk.h;
                    for (j = w * h - 1, k = inblk.offset + (h - 1) * inblk.scanw + w - 1, jmin = w * (h - 1); j >= 0; jmin -= w)
                    {
                        for (; j >= jmin; k--, j--)
                        {
                            temp = inarr[k];
                            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                            outfarr[j] = ((float)((temp >= 0) ? temp : -(temp & 0x7FFFFFFF))) * step;
                        }
                        // Jump to beggining of previous line in input
                        k -= (inblk.scanw - w);
                    }
                    break;
                }
            }
            // Return the output code-block
            return(cblk);
        }