Esempio n. 1
0
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            if (c < 0 || c >= this.nc)
            {
                throw new ArgumentOutOfRangeException("c");
            }

            blk.offset = 0;
            blk.scanw = blk.w;
            blk.progressive = false;
            blk.Data = this.GetDataArray(blk.ulx, blk.uly, blk.w, blk.h);

            return blk;
        }
Esempio n. 2
0
        /// <summary> Returns, in the blk argument, a block of image data containing the
        /// specifed rectangular area, in the specified component. The data is
        /// returned, as a copy of the internal data, therefore the returned data
        /// can be modified "in place".
        ///
        /// <p>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
        /// and 'h' members of the 'blk' argument, relative to the current
        /// tile. These members are not modified by this method. The 'offset' of
        /// the returned data is 0, and the 'scanw' is the same as the block's
        /// width. See the 'DataBlk' class.</p>
        ///
        /// <p>This method, in general, is less efficient than the
        /// 'getInternCompData()' method since, in general, it copies the
        /// data. However if the array of returned data is to be modified by the
        /// caller then this method is preferable.</p>
        ///
        /// <p>If the data array in 'blk' is 'null', then a new one is created. If
        /// the data array is not 'null' then it is reused, and it must be large
        /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
        /// or an 'IndexOutOfBoundsException' is thrown by the Java system.</p>
        ///
        /// <p>The returned data may have its 'progressive' attribute set. In this
        /// case the returned data is only an approximation of the "final"
        /// data.</p>
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to return,
        /// relative to the current tile. If it contains a non-null data array,
        /// then it must be large enough. If it contains a null data array a new
        /// one is created. Some fields in this object are modified to return the
        /// data.
        ///
        /// </param>
        /// <param name="c">The index of the component from which to get the data.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getInternCompData">
        ///
        /// </seealso>
        public DataBlk getCompData(DataBlk blk, int c)
        {
            // Check that block is inside tile
            if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c])
            {
                throw new System.ArgumentException("Block is outside the tile");
            }
            // Translate to the source's coordinates
            //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'"
            int incx = (int)System.Math.Ceiling(x0siz / (double)src.getCompSubsX(c));
            //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'"
            int incy = (int)System.Math.Ceiling(y0siz / (double)src.getCompSubsY(c));

            blk.ulx -= incx;
            blk.uly -= incy;
            blk      = src.getCompData(blk, c);
            // Translate back to the tiled coordinates
            blk.ulx += incx;
            blk.uly += incy;
            return(blk);
        }
Esempio n. 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>
		/// 
		/// <p>The 'ulx' and 'uly' members of the returned 'DataBlk' object contain
		/// the coordinates of the top-left corner of the block, with respect to
		/// the tile, not the subband.</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 requested code-block in the current tile for component 'c'.
		/// 
		/// </returns>
		/// <seealso cref="DataBlk">
		/// 
		/// </seealso>
		public virtual DataBlk getInternCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
		{
			int i, j, k, wrap; // mi removed
			int ulx, uly, w, h;
			int[] data; // local copy of quantized data
			int tmp;
			//int limit;
			
			// Get data block from entropy decoder
			cblk = src.getInternCodeBlock(c, m, n, sb, cblk);
			
			// If there are no ROIs in the tile, Or if we already got all blocks
			bool noRoiInTile = false;
			if (mss == null || mss.getTileCompVal(TileIdx, c) == null)
				noRoiInTile = true;
			
			if (noRoiInTile || cblk == null)
			{
				return cblk;
			}
			data = (int[]) cblk.Data;
			ulx = cblk.ulx;
			uly = cblk.uly;
			w = cblk.w;
			h = cblk.h;
			
			// Scale coefficients according to magnitude. If the magnitude of a
			// coefficient is lower than 2 pow 31-magbits then it is a background
			// coeff and should be up-scaled
			int boost = ((System.Int32) mss.getTileCompVal(TileIdx, c));
			int mask = ((1 << sb.magbits) - 1) << (31 - sb.magbits);
			int mask2 = (~ mask) & 0x7FFFFFFF;
			
			wrap = cblk.scanw - w;
			i = cblk.offset + cblk.scanw * (h - 1) + w - 1;
			for (j = h; j > 0; j--)
			{
				for (k = w; k > 0; k--, i--)
				{
					tmp = data[i];
					if ((tmp & mask) == 0)
					{
						// BG
						data[i] = (tmp & unchecked((int) 0x80000000)) | (tmp << boost);
					}
					else
					{
						// ROI
						if ((tmp & mask2) != 0)
						{
							// decoded more than magbits bit-planes, set
							// quantization mid-interval approx. bit just after
							// the magbits.
							data[i] = (tmp & (~ mask2)) | (1 << (30 - sb.magbits));
						}
					}
				}
				i -= wrap;
			}
			return cblk;
		}
Esempio n. 4
0
        /// <summary> Returns, in the blk argument, a block of image data containing the
        /// specifed rectangular area, in the specified component. The data is
        /// returned, as a copy of the internal data, therefore the returned data
        /// can be modified "in place".
        /// 
        /// <P> After being read the coefficients are level shifted by subtracting
        /// 2^(nominal bit range - 1)
        /// 
        /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
        /// and 'h' members of the 'blk' argument, relative to the current
        /// tile. These members are not modified by this method. The 'offset' of
        /// the returned data is 0, and the 'scanw' is the same as the block's
        /// width. See the 'DataBlk' class.
        /// 
        /// <P>If the data array in 'blk' is 'null', then a new one is created. If
        /// the data array is not 'null' then it is reused, and it must be large
        /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
        /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
        /// 
        /// <P>The returned data has its 'progressive' attribute unset
        /// (i.e. false).
        /// 
        /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
        /// used. The exception is passed to its handleException method. The action
        /// that is taken depends on the action that has been registered in
        /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
        /// 
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. If it contains a non-null data array, then it must have the
        /// correct dimensions. If it contains a null data array a new one is
        /// created. The fields in this object are modified to return the data.
        /// 
        /// </param>
        /// <param name="c">The index of the component from which to get the data. Only
        /// 0,1 and 2 are valid.
        /// 
        /// </param>
        /// <returns> The requested DataBlk
        /// 
        /// </returns>
        /// <seealso cref="getInternCompData">
        /// 
        /// </seealso>
        /// <seealso cref="JJ2KExceptionHandler">
        /// 
        /// </seealso>
        public override DataBlk getCompData(DataBlk blk, int c)
        {
            // NOTE: can not directly call getInterCompData since that returns
            // internally buffered data.
            int ulx, uly, w, h;

            // Check type of block provided as an argument
            if (blk.DataType != DataBlk.TYPE_INT)
            {
                DataBlkInt tmp = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                blk = tmp;
            }

            int[] bakarr = (int[])blk.Data;
            // Save requested block size
            ulx = blk.ulx;
            uly = blk.uly;
            w = blk.w;
            h = blk.h;
            // Force internal data buffer to be different from external
            blk.Data = null;
            getInternCompData(blk, c);
            // Copy the data
            if (bakarr == null)
            {
                bakarr = new int[w * h];
            }
            if (blk.offset == 0 && blk.scanw == w)
            {
                // Requested and returned block buffer are the same size
                // CONVERSION PROBLEM?
                Array.Copy((System.Array)blk.Data, 0, (System.Array)bakarr, 0, w * h);
            }
            else
            {
                // Requested and returned block are different
                for (int i = h - 1; i >= 0; i--)
                {
                    // copy line by line
                    // CONVERSION PROBLEM?
                    Array.Copy((System.Array)blk.Data, blk.offset + i * blk.scanw, (System.Array)bakarr, i * w, w);
                }
            }
            blk.Data = bakarr;
            blk.offset = 0;
            blk.scanw = blk.w;
            return blk;
        }
Esempio n. 5
0
		/// <summary> Conceals decoding errors detected in the last bit-plane. The
		/// concealement resets the state of the decoded data to what it was before
		/// the decoding of bit-plane 'bp' started. No more data should be decoded
		/// after this method is called for this code-block's data to which it is
		/// applied.
		/// 
		/// </summary>
		/// <param name="cblk">The code-block's data
		/// 
		/// </param>
		/// <param name="bp">The last decoded bit-plane (which contains errors).
		/// 
		/// </param>
		private void  conceal(DataBlk cblk, int bp)
		{
			int l; // line index
			int k; // array index
			int kmax; // 'k' limit
			int dk; // Value of data[k]
			int[] data; // the data array
			int setmask; // Bitmask to set approximation to 1/2 of
			// known interval on significant data
			int resetmask; // Bitmask to erase all the data from
			// bit-plane 'bp' 
			
			// Initialize masks
			setmask = 1 << bp;
			resetmask = (- 1) << (bp);
			
			// Get the data array
			data = (int[]) cblk.Data;
			
			// Visit each sample, apply the reset mask to it and add an
			// approximation if significant.
			for (l = cblk.h - 1, k = cblk.offset; l >= 0; l--)
			{
				for (kmax = k + cblk.w; k < kmax; k++)
				{
					dk = data[k];
					if ((dk & resetmask & 0x7FFFFFFF) != 0)
					{
						// Something was decoded in previous bit-planes => set the
						// approximation for previous bit-plane
						data[k] = (dk & resetmask) | setmask;
					}
					else
					{
						// Was insignificant in previous bit-planes = set to zero
						data[k] = 0;
					}
				}
				k += cblk.scanw - cblk.w;
			}
		}
Esempio n. 6
0
        /// <summary> Performs the inverse wavelet transform on the whole component. It
        /// iteratively reconstructs the subbands from leaves up to the root
        /// node. This method is recursive, the first call to it the 'sb' must be
        /// the root of the subband tree. The method will then process the entire
        /// subband tree by calling itslef recursively.
        /// 
        /// </summary>
        /// <param name="img">The buffer for the image/wavelet data.
        /// 
        /// </param>
        /// <param name="sb">The subband to reconstruct.
        /// 
        /// </param>
        /// <param name="c">The index of the component to reconstruct 
        /// 
        /// </param>
        private void waveletTreeReconstruction(DataBlk img, SubbandSyn sb, int c)
        {
            DataBlk subbData;

            // If the current subband is a leaf then get the data from the source
            if (!sb.isNode)
            {
                int i, m, n;
                System.Object src_data, dst_data;
                Coord ncblks;

                if (sb.w == 0 || sb.h == 0)
                {
                    return ; // If empty subband do nothing
                }

                // Get all code-blocks in subband
                if (dtype == DataBlk.TYPE_INT)
                {
                    subbData = new DataBlkInt();
                }
                else
                {
                    subbData = new DataBlkFloat();
                }
                ncblks = sb.numCb;
                dst_data = img.Data;
                for (m = 0; m < ncblks.y; m++)
                {
                    for (n = 0; n < ncblks.x; n++)
                    {
                        subbData = src.getInternCodeBlock(c, m, n, sb, subbData);
                        src_data = subbData.Data;

                        // Copy the data line by line
                        for (i = subbData.h - 1; i >= 0; i--)
                        {
                            // CONVERSION PROBLEM
                            Array.Copy((System.Array)src_data, subbData.offset + i * subbData.scanw, (System.Array)dst_data, (subbData.uly + i) * img.w + subbData.ulx, subbData.w);
                        }
                    }
                }
            }
            else if (sb.isNode)
            {
                // Reconstruct the lower resolution levels if the current subbands
                // is a node

                //Perform the reconstruction of the LL subband
                waveletTreeReconstruction(img, (SubbandSyn) sb.LL, c);

                if (sb.resLvl <= reslvl - maxImgRes + ndl[c])
                {
                    //Reconstruct the other subbands
                    waveletTreeReconstruction(img, (SubbandSyn) sb.HL, c);
                    waveletTreeReconstruction(img, (SubbandSyn) sb.LH, c);
                    waveletTreeReconstruction(img, (SubbandSyn) sb.HH, c);

                    //Perform the 2D wavelet decomposition of the current subband
                    wavelet2DReconstruction(img, (SubbandSyn) sb, c);
                }
            }
        }
Esempio n. 7
0
		/// <summary> Returns, in the blk argument, a block of image data containing the
		/// specifed rectangular area, in the specified component, using the
		/// 'transfer type' specified in the block given as argument. The data is
		/// returned, as a copy of the internal data, therefore the returned data
		/// can be modified "in place".
		/// 
		/// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
		/// and 'h' members of the 'blk' argument, relative to the current
		/// tile. These members are not modified by this method. The 'offset' of
		/// the returned data is 0, and the 'scanw' is the same as the block's
		/// width. See the 'DataBlk' class.
		/// 
		/// <P>This method, in general, is less efficient than the
		/// 'getInternCompData()' method since, in general, it copies the
		/// data. However if the array of returned data is to be modified by the
		/// caller then this method is preferable.
		/// 
		/// <P>If the data array in 'blk' is 'null', then a new one is created. If
		/// the data array is not 'null' then it is reused, and it must be large
		/// enough to contain the block's data. Otherwise an 'ArrayStoreException'
		/// or an 'IndexOutOfBoundsException' is thrown by the Java system.
		/// 
		/// <P>The returned data may have its 'progressive' attribute set. In this
		/// case the returned data is only an approximation of the "final" data.
		/// 
		/// </summary>
		/// <param name="blk">Its coordinates and dimensions specify the area to return,
		/// relative to the current tile. If it contains a non-null data array,
		/// then it must be large enough. If it contains a null data array a new
		/// one is created. Some fields in this object are modified to return the
		/// data.
		/// 
		/// </param>
		/// <param name="c">The index of the component from which to get the data.
		/// 
		/// </param>
		/// <seealso cref="getInternCompData">
		/// 
		/// </seealso>
		public virtual DataBlk getCompData(DataBlk blk, int c)
		{
			return getData(blk, c, false);
		}
Esempio n. 8
0
		/// <summary> Implements the 'getInternCompData()' and the 'getCompData()'
		/// methods. The 'intern' flag signals which of the two methods should run
		/// as.
		/// 
		/// </summary>
		/// <param name="blk">The data block to get.
		/// 
		/// </param>
		/// <param name="c">The index of the component from which to get the data.
		/// 
		/// </param>
		/// <param name="intern">If true behave as 'getInternCompData(). Otherwise behave
		/// as 'getCompData()'
		/// 
		/// </param>
		/// <returns> The requested data block
		/// 
		/// </returns>
		/// <seealso cref="getInternCompData">
		/// 
		/// </seealso>
		/// <seealso cref="getCompData">
		/// 
		/// </seealso>
		private DataBlk getData(DataBlk blk, int c, bool intern)
		{
			DataBlk reqBlk; // Reference to block used in request to source
			
			// Keep request data type
			int otype = blk.DataType;
			
			if (otype == srcBlk.DataType)
			{
				// Probably requested type is same as source type
				reqBlk = blk;
			}
			else
			{
				// Probably requested type is not the same as source type
				reqBlk = srcBlk;
				// We need to copy requested coordinates and size
				reqBlk.ulx = blk.ulx;
				reqBlk.uly = blk.uly;
				reqBlk.w = blk.w;
				reqBlk.h = blk.h;
			}
			
			// Get source data block
			if (intern)
			{
				// We can use the intern variant
				srcBlk = src.getInternCompData(reqBlk, c);
			}
			else
			{
				// Do not use the intern variant. Note that this is not optimal
				// since if we are going to convert below then we could have used
				// the intern variant. But there is currently no way to know if we
				// will need to do conversion or not before getting the data.
				srcBlk = src.getCompData(reqBlk, c);
			}
			
			// Check if casting is needed
			if (srcBlk.DataType == otype)
			{
				return srcBlk;
			}
			
			int i;
			int k, kSrc, kmin;
			float mult;
			int w = srcBlk.w;
			int h = srcBlk.h;
			
			switch (otype)
			{
				
				case DataBlk.TYPE_FLOAT:  // Cast INT -> FLOAT
					
					float[] farr;
					int[] srcIArr;
					
					// Get data array from resulting blk
					farr = (float[]) blk.Data;
					if (farr == null || farr.Length < w * h)
					{
						farr = new float[w * h];
						blk.Data = farr;
					}
					
					blk.scanw = srcBlk.w;
					blk.offset = 0;
					blk.progressive = srcBlk.progressive;
					srcIArr = (int[]) srcBlk.Data;
					
					// Cast data from source to blk
					fp = src.getFixedPoint(c);
					if (fp != 0)
					{
						mult = 1.0f / (1 << fp);
						for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--)
						{
							for (kmin = k - w; k > kmin; k--, kSrc--)
							{
								farr[k] = ((srcIArr[kSrc] * mult));
							}
							// Jump to geggining of next line in source
							kSrc -= (srcBlk.scanw - w);
						}
					}
					else
					{
						for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--)
						{
							for (kmin = k - w; k > kmin; k--, kSrc--)
							{
								//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'"
								farr[k] = ((float) (srcIArr[kSrc]));
							}
							// Jump to geggining of next line in source
							kSrc -= (srcBlk.scanw - w);
						}
					}
					break; // End of cast INT-> FLOAT
				
				
				case DataBlk.TYPE_INT:  // cast FLOAT -> INT
					int[] iarr;
					float[] srcFArr;
					
					// Get data array from resulting blk
					iarr = (int[]) blk.Data;
					if (iarr == null || iarr.Length < w * h)
					{
						iarr = new int[w * h];
						blk.Data = iarr;
					}
					blk.scanw = srcBlk.w;
					blk.offset = 0;
					blk.progressive = srcBlk.progressive;
					srcFArr = (float[]) srcBlk.Data;
					
					// Cast data from source to blk
					if (fp != 0)
					{
						//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'"
						mult = (float) (1 << fp);
						for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--)
						{
							for (kmin = k - w; k > kmin; k--, kSrc--)
							{
								if (srcFArr[kSrc] > 0.0f)
								{
									//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'"
									iarr[k] = (int) (srcFArr[kSrc] * mult + 0.5f);
								}
								else
								{
									//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
									iarr[k] = (int) (srcFArr[kSrc] * mult - 0.5f);
								}
							}
							// Jump to geggining of next line in source
							kSrc -= (srcBlk.scanw - w);
						}
					}
					else
					{
						for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--)
						{
							for (kmin = k - w; k > kmin; k--, kSrc--)
							{
								if (srcFArr[kSrc] > 0.0f)
								{
									//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'"
									iarr[k] = (int) (srcFArr[kSrc] + 0.5f);
								}
								else
								{
									//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
									iarr[k] = (int) (srcFArr[kSrc] - 0.5f);
								}
							}
							// Jump to geggining of next line in source
							kSrc -= (srcBlk.scanw - w);
						}
					}
					break; // End cast FLOAT -> INT
				
				default: 
					throw new System.ArgumentException("Only integer and float data " + "are " + "supported by JJ2000");
				
			}
			return blk;
		}
Esempio n. 9
0
		/// <summary> Apply the component transformation associated with the current tile. If
		/// no component transformation has been requested by the user, data are
		/// not modified. Else, appropriate method is called (forwRCT or forwICT).
		/// 
		/// </summary>
		/// <seealso cref="forwRCT">
		/// 
		/// </seealso>
		/// <seealso cref="forwICT">
		/// 
		/// </seealso>
		/// <param name="blk">Determines the rectangular area to return.
		/// 
		/// </param>
		/// <param name="c">Index of the output component.
		/// 
		/// </param>
		/// <returns> The requested DataBlk
		/// 
		/// </returns>
		public virtual DataBlk getInternCompData(DataBlk blk, int c)
		{
			switch (transfType)
			{
				
				case NONE: 
					return src.getInternCompData(blk, c);
				
				case FORW_RCT: 
					return forwRCT(blk, c);
				
				case FORW_ICT: 
					return forwICT(blk, c);
				
				default: 
					throw new System.ArgumentException("Non JPEG 2000 part 1 " + "component" + " transformation for tile: " + tIdx);
				
			}
		}
Esempio n. 10
0
		/// <summary> Performs the forward wavelet transform on the whole band. It
		/// iteratively decomposes the subbands from the top node to the leaves.
		/// 
		/// </summary>
		/// <param name="band">The band containing the float data to decompose
		/// 
		/// </param>
		/// <param name="subband">The structure containing the coordinates of the current
		/// subband in the whole band to decompose.
		/// 
		/// </param>
		/// <param name="c">The index of the current component to decompose
		/// 
		/// </param>
		private void  waveletTreeDecomposition(DataBlk band, SubbandAn subband, int c)
		{
			
			//If the current subband is a leaf then nothing to be done (a leaf is
			//not decomposed).
			if (!subband.isNode)
			{
				return ;
			}
			else
			{
				//Perform the 2D wavelet decomposition of the current subband
				wavelet2DDecomposition(band, (SubbandAn) subband, c);
				
				//Perform the decomposition of the four resulting subbands
				waveletTreeDecomposition(band, (SubbandAn) subband.HH, c);
				waveletTreeDecomposition(band, (SubbandAn) subband.LH, c);
				waveletTreeDecomposition(band, (SubbandAn) subband.HL, c);
				waveletTreeDecomposition(band, (SubbandAn) subband.LL, c);
			}
		}
Esempio n. 11
0
 /// <summary> Returns, in the blk argument, a block of image data containing the
 /// specifed rectangular area, in the specified component, using the
 /// 'transfer type' defined in the block given as argument. The data is
 /// returned, as a reference to the internal data, if any, instead of as a
 /// copy, therefore the returned data should not be modified.
 ///
 /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
 /// and 'h' members of the 'blk' argument, relative to the current
 /// tile. These members are not modified by this method. The 'offset' and
 /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class.
 ///
 /// <P> If source data and expected data (blk) are using the same type,
 /// block returned without any modification. If not appropriate cast is
 /// used.
 ///
 /// <P>This method, in general, is more efficient than the 'getCompData()'
 /// method since it may not copy the data. However if the array of returned
 /// data is to be modified by the caller then the other method is probably
 /// preferable.
 ///
 /// <P>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one
 /// is created if necessary. The implementation of this interface may
 /// choose to return the same array or a new one, depending on what is more
 /// efficient. Therefore, the data array in <tt>blk</tt> prior to the
 /// method call should not be considered to contain the returned data, a
 /// new array may have been created. Instead, get the array from
 /// <tt>blk</tt> after the method has returned.
 ///
 /// <P>The returned data may have its 'progressive' attribute set. In this
 /// case the returned data is only an approximation of the "final" data.
 ///
 /// </summary>
 /// <param name="blk">Its coordinates and dimensions specify the area to return,
 /// relative to the current tile. Some fields in this object are modified
 /// to return the data.
 ///
 /// </param>
 /// <param name="c">The index of the component from which to get the data.
 ///
 /// </param>
 /// <returns> The requested DataBlk
 ///
 /// </returns>
 /// <seealso cref="getCompData">
 ///
 /// </seealso>
 public DataBlk getInternCompData(DataBlk blk, int c)
 {
     return(getData(blk, c, true));
 }
Esempio n. 12
0
        /// <summary> Implements the 'getInternCompData()' and the 'getCompData()'
        /// methods. The 'intern' flag signals which of the two methods should run
        /// as.
        ///
        /// </summary>
        /// <param name="blk">The data block to get.
        ///
        /// </param>
        /// <param name="c">The index of the component from which to get the data.
        ///
        /// </param>
        /// <param name="intern">If true behave as 'getInternCompData(). Otherwise behave
        /// as 'getCompData()'
        ///
        /// </param>
        /// <returns> The requested data block
        ///
        /// </returns>
        /// <seealso cref="getInternCompData">
        ///
        /// </seealso>
        /// <seealso cref="getCompData">
        ///
        /// </seealso>
        private DataBlk getData(DataBlk blk, int c, bool intern)
        {
            DataBlk reqBlk; // Reference to block used in request to source

            // Keep request data type
            int otype = blk.DataType;

            if (otype == srcBlk.DataType)
            {
                // Probably requested type is same as source type
                reqBlk = blk;
            }
            else
            {
                // Probably requested type is not the same as source type
                reqBlk = srcBlk;
                // We need to copy requested coordinates and size
                reqBlk.ulx = blk.ulx;
                reqBlk.uly = blk.uly;
                reqBlk.w   = blk.w;
                reqBlk.h   = blk.h;
            }

            // Get source data block
            if (intern)
            {
                // We can use the intern variant
                srcBlk = src.getInternCompData(reqBlk, c);
            }
            else
            {
                // Do not use the intern variant. Note that this is not optimal
                // since if we are going to convert below then we could have used
                // the intern variant. But there is currently no way to know if we
                // will need to do conversion or not before getting the data.
                srcBlk = src.getCompData(reqBlk, c);
            }

            // Check if casting is needed
            if (srcBlk.DataType == otype)
            {
                return(srcBlk);
            }

            int   i;
            int   k, kSrc, kmin;
            float mult;
            int   w = srcBlk.w;
            int   h = srcBlk.h;

            switch (otype)
            {
            case DataBlk.TYPE_FLOAT:     // Cast INT -> FLOAT

                float[] farr;
                int[]   srcIArr;

                // Get data array from resulting blk
                farr = (float[])blk.Data;
                if (farr == null || farr.Length < w * h)
                {
                    farr     = new float[w * h];
                    blk.Data = farr;
                }

                blk.scanw       = srcBlk.w;
                blk.offset      = 0;
                blk.progressive = srcBlk.progressive;
                srcIArr         = (int[])srcBlk.Data;

                // Cast data from source to blk
                fp = src.getFixedPoint(c);
                if (fp != 0)
                {
                    mult = 1.0f / (1 << fp);
                    for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1;
                         i >= 0;
                         i--)
                    {
                        for (kmin = k - w; k > kmin; k--, kSrc--)
                        {
                            farr[k] = ((srcIArr[kSrc] * mult));
                        }
                        // Jump to geggining of next line in source
                        kSrc -= (srcBlk.scanw - w);
                    }
                }
                else
                {
                    for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1;
                         i >= 0;
                         i--)
                    {
                        for (kmin = k - w; k > kmin; k--, kSrc--)
                        {
                            //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'"
                            farr[k] = ((float)(srcIArr[kSrc]));
                        }
                        // Jump to geggining of next line in source
                        kSrc -= (srcBlk.scanw - w);
                    }
                }
                break;     // End of cast INT-> FLOAT


            case DataBlk.TYPE_INT:     // cast FLOAT -> INT
                int[]   iarr;
                float[] srcFArr;

                // Get data array from resulting blk
                iarr = (int[])blk.Data;
                if (iarr == null || iarr.Length < w * h)
                {
                    iarr     = new int[w * h];
                    blk.Data = iarr;
                }
                blk.scanw       = srcBlk.w;
                blk.offset      = 0;
                blk.progressive = srcBlk.progressive;
                srcFArr         = (float[])srcBlk.Data;

                // Cast data from source to blk
                if (fp != 0)
                {
                    //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'"
                    mult = (float)(1 << fp);
                    for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1;
                         i >= 0;
                         i--)
                    {
                        for (kmin = k - w; k > kmin; k--, kSrc--)
                        {
                            if (srcFArr[kSrc] > 0.0f)
                            {
                                //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'"
                                iarr[k] = (int)(srcFArr[kSrc] * mult + 0.5f);
                            }
                            else
                            {
                                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                                iarr[k] = (int)(srcFArr[kSrc] * mult - 0.5f);
                            }
                        }
                        // Jump to geggining of next line in source
                        kSrc -= (srcBlk.scanw - w);
                    }
                }
                else
                {
                    for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1;
                         i >= 0;
                         i--)
                    {
                        for (kmin = k - w; k > kmin; k--, kSrc--)
                        {
                            if (srcFArr[kSrc] > 0.0f)
                            {
                                //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'"
                                iarr[k] = (int)(srcFArr[kSrc] + 0.5f);
                            }
                            else
                            {
                                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                                iarr[k] = (int)(srcFArr[kSrc] - 0.5f);
                            }
                        }
                        // Jump to geggining of next line in source
                        kSrc -= (srcBlk.scanw - w);
                    }
                }
                break;     // End cast FLOAT -> INT

            default:
                throw new System.ArgumentException("Only integer and float data " + "are " + "supported by JJ2000");
            }
            return(blk);
        }
Esempio n. 13
0
 /// <summary> Returns, in the blk argument, a block of image data containing the
 /// specifed rectangular area, in the specified component, using the
 /// 'transfer type' specified in the block given as argument. The data is
 /// returned, as a copy of the internal data, therefore the returned data
 /// can be modified "in place".
 ///
 /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
 /// and 'h' members of the 'blk' argument, relative to the current
 /// tile. These members are not modified by this method. The 'offset' of
 /// the returned data is 0, and the 'scanw' is the same as the block's
 /// width. See the 'DataBlk' class.
 ///
 /// <P>This method, in general, is less efficient than the
 /// 'getInternCompData()' method since, in general, it copies the
 /// data. However if the array of returned data is to be modified by the
 /// caller then this method is preferable.
 ///
 /// <P>If the data array in 'blk' is 'null', then a new one is created. If
 /// the data array is not 'null' then it is reused, and it must be large
 /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
 /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
 ///
 /// <P>The returned data may have its 'progressive' attribute set. In this
 /// case the returned data is only an approximation of the "final" data.
 ///
 /// </summary>
 /// <param name="blk">Its coordinates and dimensions specify the area to return,
 /// relative to the current tile. If it contains a non-null data array,
 /// then it must be large enough. If it contains a null data array a new
 /// one is created. Some fields in this object are modified to return the
 /// data.
 ///
 /// </param>
 /// <param name="c">The index of the component from which to get the data.
 ///
 /// </param>
 /// <seealso cref="getInternCompData">
 ///
 /// </seealso>
 public virtual DataBlk getCompData(DataBlk blk, int c)
 {
     return(getData(blk, c, false));
 }
Esempio n. 14
0
		/// <summary> Performs the significance propagation pass on the specified data and
		/// bit-plane. It decodes all insignificant samples which have, at least,
		/// one of its immediate eight neighbors already significant, using the ZC
		/// and SC primitives as needed. It toggles the "visited" state bit to 1
		/// for all those samples.
		/// 
		/// <p>This method also checks for segmentation markers if those are
		/// present and returns true if an error is detected, or false
		/// otherwise. If an error is detected it means that the bit stream
		/// contains some erroneous bit that have led to the decoding of incorrect
		/// data. This data affects the whole last decoded bit-plane
		/// (i.e. 'bp'). If 'true' is returned the 'conceal' method should be
		/// called and no more passes should be decoded for this code-block's bit
		/// stream.</p>
		/// 
		/// </summary>
		/// <param name="cblk">The code-block data to decode
		/// 
		/// </param>
		/// <param name="mq">The MQ-coder to use
		/// 
		/// </param>
		/// <param name="bp">The bit-plane to decode
		/// 
		/// </param>
		/// <param name="state">The state information for the code-block
		/// 
		/// </param>
		/// <param name="zc_lut">The ZC lookup table to use in ZC.
		/// 
		/// </param>
		/// <param name="isterm">If this pass has been terminated. If the pass has been
		/// terminated it can be used to check error resilience.
		/// 
		/// </param>
		/// <returns> True if an error was detected in the bit stream, false
		/// otherwise.
		/// 
		/// </returns>
		private bool sigProgPass(DataBlk cblk, MQDecoder mq, int bp, int[] state, int[] zc_lut, bool isterm)
		{
			int j, sj; // The state index for line and stripe
			int k, sk; // The data index for line and stripe
			int dscanw; // The data scan-width
			int sscanw; // The state scan-width
			int jstep; // Stripe to stripe step for 'sj'
			int kstep; // Stripe to stripe step for 'sk'
			int stopsk; // The loop limit on the variable sk
			int csj; // Local copy (i.e. cached) of 'state[j]'
			int setmask; // The mask to set current and lower bit-planes to 1/2
			// approximation
			int sym; // The symbol to code
			int ctxt; // The context to use
			int[] data; // The data buffer
			int s; // The stripe index
			bool causal; // Flag to indicate if stripe-causal context
			// formation is to be used
			int nstripes; // The number of stripes in the code-block
			int sheight; // Height of the current stripe
			int off_ul, off_ur, off_dr, off_dl; // offsets
			bool error; // The error condition
			
			// Initialize local variables
			dscanw = cblk.scanw;
			sscanw = cblk.w + 2;
			jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - cblk.w;
			kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - cblk.w;
			setmask = (3 << bp) >> 1;
			data = (int[]) cblk.Data;
			nstripes = (cblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
			causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0;
			
			// Pre-calculate offsets in 'state' for diagonal neighbors
			off_ul = - sscanw - 1; // up-left
			off_ur = - sscanw + 1; // up-right
			off_dr = sscanw + 1; // down-right
			off_dl = sscanw - 1; // down-left
			
			// Decode stripe by stripe
			sk = cblk.offset;
			sj = sscanw + 1;
			for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
			{
				sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:cblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
				stopsk = sk + cblk.w;
				// Scan by set of 1 stripe column at a time
				for (; sk < stopsk; sk++, sj++)
				{
					// Do half top of column
					j = sj;
					csj = state[j];
					// If any of the two samples is not significant and has a
					// non-zero context (i.e. some neighbor is significant) we can 
					// not skip them
					if ((((~ csj) & (csj << 2)) & SIG_MASK_R1R2) != 0)
					{
						k = sk;
						// Scan first row
						if ((csj & (STATE_SIG_R1 | STATE_NZ_CTXT_R1)) == STATE_NZ_CTXT_R1)
						{
							// Use zero coding
							if (mq.decodeSymbol(zc_lut[csj & ZC_MASK]) != 0)
							{
								// Became significant
								// Use sign coding
								ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R1)) & SC_MASK];
								sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
								// Update data
								data[k] = (sym << 31) | setmask;
								// Update state information (significant bit,
								// visited bit, neighbor significant bit of
								// neighbors, non zero context of neighbors, sign
								// of neighbors)
								if (!causal)
								{
									// If in causal mode do not change contexts of 
									// previous stripe.
									state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
									state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
								}
								// Update sign state information of neighbors
								if (sym != 0)
								{
									csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
									if (!causal)
									{
										// If in causal mode do not change
										// contexts of previous stripe.
										state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
									}
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
								}
								else
								{
									csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
									if (!causal)
									{
										// If in causal mode do not change
										// contexts of previous stripe.
										state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
									}
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
								}
							}
							else
							{
								csj |= STATE_VISITED_R1;
							}
						}
						if (sheight < 2)
						{
							state[j] = csj;
							continue;
						}
						// Scan second row
						if ((csj & (STATE_SIG_R2 | STATE_NZ_CTXT_R2)) == STATE_NZ_CTXT_R2)
						{
							k += dscanw;
							// Use zero coding
							if (mq.decodeSymbol(zc_lut[(SupportClass.URShift(csj, STATE_SEP)) & ZC_MASK]) != 0)
							{
								// Became significant
								// Use sign coding
								ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
								sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
								// Update data
								data[k] = (sym << 31) | setmask;
								// Update state information (significant bit,
								// visited bit, neighbor significant bit of
								// neighbors, non zero context of neighbors, sign
								// of neighbors)
								state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
								state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
								// Update sign state information of neighbors
								if (sym != 0)
								{
									csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
									state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
								}
								else
								{
									csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
									state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
								}
							}
							else
							{
								csj |= STATE_VISITED_R2;
							}
						}
						state[j] = csj;
					}
					// Do half bottom of column
					if (sheight < 3)
						continue;
					j += sscanw;
					csj = state[j];
					// If any of the two samples is not significant and has a
					// non-zero context (i.e. some neighbor is significant) we can 
					// not skip them
					if ((((~ csj) & (csj << 2)) & SIG_MASK_R1R2) != 0)
					{
						k = sk + (dscanw << 1);
						// Scan first row
						if ((csj & (STATE_SIG_R1 | STATE_NZ_CTXT_R1)) == STATE_NZ_CTXT_R1)
						{
							// Use zero coding
							if (mq.decodeSymbol(zc_lut[csj & ZC_MASK]) != 0)
							{
								// Became significant
								// Use sign coding
								ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R1)) & SC_MASK];
								sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
								// Update data
								data[k] = (sym << 31) | setmask;
								// Update state information (significant bit,
								// visited bit, neighbor significant bit of
								// neighbors, non zero context of neighbors, sign
								// of neighbors)
								state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
								state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
								// Update sign state information of neighbors
								if (sym != 0)
								{
									csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
									state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
								}
								else
								{
									csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
									state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
								}
							}
							else
							{
								csj |= STATE_VISITED_R1;
							}
						}
						if (sheight < 4)
						{
							state[j] = csj;
							continue;
						}
						// Scan second row
						if ((csj & (STATE_SIG_R2 | STATE_NZ_CTXT_R2)) == STATE_NZ_CTXT_R2)
						{
							k += dscanw;
							// Use zero coding
							if (mq.decodeSymbol(zc_lut[(SupportClass.URShift(csj, STATE_SEP)) & ZC_MASK]) != 0)
							{
								// Became significant
								// Use sign coding
								ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
								sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
								// Update data
								data[k] = (sym << 31) | setmask;
								// Update state information (significant bit,
								// visited bit, neighbor significant bit of
								// neighbors, non zero context of neighbors, sign
								// of neighbors)
								state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
								state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
								// Update sign state information of neighbors
								if (sym != 0)
								{
									csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
									state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
								}
								else
								{
									csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
									state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
								}
							}
							else
							{
								csj |= STATE_VISITED_R2;
							}
						}
						state[j] = csj;
					}
				}
			}
			
			error = false;
			
			// Check the error resilience termination
			if (isterm && (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0)
			{
				error = mq.checkPredTerm();
			}
			
			// Reset the MQ context states if we need to
			if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ) != 0)
			{
				mq.resetCtxts();
			}
			
			// Return error condition
			return error;
		}
Esempio n. 15
0
		/// <summary> Returns the specified code-block in the current tile for the specified
		/// component, as a copy (see below).
		/// 
		/// <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>The data returned by this method is always a copy of the internal
		/// data of this object, if any, and it can be modified "in place" without
		/// any problems after being returned. The 'offset' of the returned data is
		/// 0, and the 'scanw' is the same as the code-block width. See the
		/// 'DataBlk' class.
		/// 
		/// <P>The 'ulx' and 'uly' members of the returned 'DataBlk' object
		/// contain the coordinates of the top-left corner of the block, with
		/// respect to the tile, not the subband.
		/// 
		/// </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 getCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
		{
			//long stime = 0L; // Start time for timed sections
			int[] zc_lut; // The ZC lookup table to use
			int[] out_data; // The outupt data buffer
			int npasses; // The number of coding passes to perform
			int curbp; // The current magnitude bit-plane (starts at 30)
			bool error; // Error indicator
			int tslen; // Length of first terminated segment
			int tsidx; // Index of current terminated segment
			ByteInputBuffer in_Renamed = null;
			
			bool isterm;
			
			// Get the code-block to decode
			srcblk = src.getCodeBlock(c, m, n, sb, 1, - 1, srcblk);
			
#if DO_TIMING
			stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
#endif

			// Retrieve options from decSpec
			options = ((System.Int32) decSpec.ecopts.getTileCompVal(tIdx, c));
			
			// Reset state
			ArrayUtil.intArraySet(state, 0);
			
			// Initialize output code-block
			if (cblk == null)
				cblk = new DataBlkInt();
			cblk.progressive = srcblk.prog;
			cblk.ulx = srcblk.ulx;
			cblk.uly = srcblk.uly;
			cblk.w = srcblk.w;
			cblk.h = srcblk.h;
			cblk.offset = 0;
			cblk.scanw = cblk.w;
			out_data = (int[]) cblk.Data;
			
			if (out_data == null || out_data.Length < srcblk.w * srcblk.h)
			{
				out_data = new int[srcblk.w * srcblk.h];
				cblk.Data = out_data;
			}
			else
			{
				// Set data values to 0
				ArrayUtil.intArraySet(out_data, 0);
			}
			
			if (srcblk.nl <= 0 || srcblk.nTrunc <= 0)
			{
				// 0 layers => no data to decode => return all 0s
				return cblk;
			}
			
			// Get the length of the first terminated segment
			tslen = (srcblk.tsLengths == null)?srcblk.dl:srcblk.tsLengths[0];
			tsidx = 0;
			// Initialize for decoding
			npasses = srcblk.nTrunc;
			if (mq == null)
			{
				in_Renamed = new ByteInputBuffer(srcblk.data, 0, tslen);
				mq = new MQDecoder(in_Renamed, NUM_CTXTS, MQ_INIT);
			}
			else
			{
				// We always start by an MQ segment
				mq.nextSegment(srcblk.data, 0, tslen);
				mq.resetCtxts();
			}
			error = false;
			
			if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0)
			{
				if (bin == null)
				{
					if (in_Renamed == null)
						in_Renamed = mq.ByteInputBuffer;
					bin = new ByteToBitInput(in_Renamed);
				}
			}
			
			// Choose correct ZC lookup table for global orientation
			switch (sb.orientation)
			{
				
				case Subband.WT_ORIENT_HL: 
					zc_lut = ZC_LUT_HL;
					break;
				
				case Subband.WT_ORIENT_LH: 
				case Subband.WT_ORIENT_LL: 
					zc_lut = ZC_LUT_LH;
					break;
				
				case Subband.WT_ORIENT_HH: 
					zc_lut = ZC_LUT_HH;
					break;
				
				default: 
					throw new System.ApplicationException("JJ2000 internal error");
				
			}
			
			// NOTE: we don't currently detect which is the last magnitude
			// bit-plane so that 'isterm' is true for the last pass of it. Doing
			// so would aid marginally in error detection with the predictable
			// error resilient MQ termination. However, determining which is the
			// last magnitude bit-plane is quite hard (due to ROI, quantization,
			// etc.)  and in any case the predictable error resilient termination
			// used without the arithmetic coding bypass and/or regular
			// termination modes is almost useless.
			
			// Loop on bit-planes and passes
			
			curbp = 30 - srcblk.skipMSBP;
			
			// Check for maximum number of bitplanes quit condition
			if (mQuit != - 1 && (mQuit * 3 - 2) < npasses)
			{
				npasses = mQuit * 3 - 2;
			}
			
			// First bit-plane has only the cleanup pass
			if (curbp >= 0 && npasses > 0)
			{
				isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP) >= curbp);
				error = cleanuppass(cblk, mq, curbp, state, zc_lut, isterm);
				npasses--;
				if (!error || !doer)
					curbp--;
			}
			
			// Other bit-planes have the three coding passes
			if (!error || !doer)
			{
				while (curbp >= 0 && npasses > 0)
				{
					
					if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (curbp < 31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP))
					{
						// Use bypass decoding mode (only all bit-planes
						// after the first 4 bit-planes).
						
						// Here starts a new raw segment
						bin.setByteArray(null, - 1, srcblk.tsLengths[++tsidx]);
						isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0;
						error = rawSigProgPass(cblk, bin, curbp, state, isterm);
						npasses--;
						if (npasses <= 0 || (error && doer))
							break;
						
						if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
						{
							// Start a new raw segment
							bin.setByteArray(null, - 1, srcblk.tsLengths[++tsidx]);
						}
						isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP > curbp));
						error = rawMagRefPass(cblk, bin, curbp, state, isterm);
					}
					else
					{
						// Do not use bypass decoding mode
						if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
						{
							// Here starts a new MQ segment
							mq.nextSegment(null, - 1, srcblk.tsLengths[++tsidx]);
						}
						isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0;
						error = sigProgPass(cblk, mq, curbp, state, zc_lut, isterm);
						npasses--;
						if (npasses <= 0 || (error && doer))
							break;
						
						if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
						{
							// Here starts a new MQ segment
							mq.nextSegment(null, - 1, srcblk.tsLengths[++tsidx]);
						}
						isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP > curbp));
						error = magRefPass(cblk, mq, curbp, state, isterm);
					}
					
					npasses--;
					if (npasses <= 0 || (error && doer))
						break;
					
					if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (curbp < 31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP)))
					{
						// Here starts a new MQ segment
						mq.nextSegment(null, - 1, srcblk.tsLengths[++tsidx]);
					}
					isterm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - srcblk.skipMSBP) >= curbp);
					error = cleanuppass(cblk, mq, curbp, state, zc_lut, isterm);
					npasses--;
					if (error && doer)
						break;
					// Goto next bit-plane
					curbp--;
				}
			}
			
			// If an error ocurred conceal it
			if (error && doer)
			{
				if (verber)
				{
					FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Error detected at bit-plane " + curbp + " in code-block (" + m + "," + n + "), sb_idx " + sb.sbandIdx + ", res. level " + sb.resLvl + ". Concealing...");
				}
				conceal(cblk, curbp);
			}
			
#if DO_TIMING
			time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
#endif
			
			// Return decoded block
			return cblk;
		}
Esempio n. 16
0
		/// <summary> Returns, in the blk argument, a block of image data containing the
		/// specifed rectangular area, in the specified component. The data is
		/// returned, as a copy of the internal data, therefore the returned data
		/// can be modified "in place".
		/// 
		/// <P> After being read the coefficients are level shifted by subtracting
		/// 2^(nominal bit range - 1)
		/// 
		/// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
		/// and 'h' members of the 'blk' argument, relative to the current
		/// tile. These members are not modified by this method. The 'offset' of
		/// the returned data is 0, and the 'scanw' is the same as the block's
		/// width. See the 'DataBlk' class.
		/// 
		/// <P>If the data array in 'blk' is 'null', then a new one is created. If
		/// the data array is not 'null' then it is reused, and it must be large
		/// enough to contain the block's data. Otherwise an 'ArrayStoreException'
		/// or an 'IndexOutOfBoundsException' is thrown by the Java system.
		/// 
		/// <P>The returned data has its 'progressive' attribute unset
		/// (i.e. false).
		/// 
		/// <P>This method just calls 'getInternCompData(blk, n)'.
		/// 
		/// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
		/// used. The exception is passed to its handleException method. The action
		/// that is taken depends on the action that has been registered in
		/// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
		/// 
		/// </summary>
		/// <param name="blk">Its coordinates and dimensions specify the area to
		/// return. If it contains a non-null data array, then it must have the
		/// correct dimensions. If it contains a null data array a new one is
		/// created. The fields in this object are modified to return the data.
		/// 
		/// </param>
		/// <param name="c">The index of the component from which to get the data. Only 0
		/// is valid.
		/// 
		/// </param>
		/// <returns> The requested DataBlk
		/// 
		/// </returns>
		/// <seealso cref="getInternCompData">
		/// 
		/// </seealso>
		/// <seealso cref="JJ2KExceptionHandler">
		/// 
		/// </seealso>
		public override DataBlk getCompData(DataBlk blk, int c)
		{
			return getInternCompData(blk, c);
		}
Esempio n. 17
0
		/// <summary> Apply forward component transformation to obtain requested component
		/// from specified block of data. Whatever the type of requested DataBlk,
		/// it always returns a DataBlkInt.
		/// 
		/// </summary>
		/// <param name="blk">Determine the rectangular area to return 
		/// 
		/// </param>
		/// <param name="c">The index of the requested component
		/// 
		/// </param>
		/// <returns> Data of requested component
		/// 
		/// </returns>
		private DataBlk forwRCT(DataBlk blk, int c)
		{
			int k, k0, k1, k2, mink, i;
			int w = blk.w; //width of output block
			int h = blk.h; //height of ouput block
			int[] outdata; //array of output data
			
			//If asking for Yr, Ur or Vr do transform
			if (c >= 0 && c <= 2)
			{
				// Check that request data type is int
				if (blk.DataType != DataBlk.TYPE_INT)
				{
					if (outBlk == null || outBlk.DataType != DataBlk.TYPE_INT)
					{
						outBlk = new DataBlkInt();
					}
					outBlk.w = w;
					outBlk.h = h;
					outBlk.ulx = blk.ulx;
					outBlk.uly = blk.uly;
					blk = outBlk;
				}
				
				//Reference to output block data array
				outdata = (int[]) blk.Data;
				
				//Create data array of blk if necessary
				if (outdata == null || outdata.Length < h * w)
				{
					outdata = new int[h * w];
					blk.Data = outdata;
				}
				
				// Block buffers for input RGB data
				int[] data0, data1, bdata; // input data arrays
				
				if (block0 == null)
					block0 = new DataBlkInt();
				if (block1 == null)
					block1 = new DataBlkInt();
				if (block2 == null)
					block2 = new DataBlkInt();
				block0.w = block1.w = block2.w = blk.w;
				block0.h = block1.h = block2.h = blk.h;
				block0.ulx = block1.ulx = block2.ulx = blk.ulx;
				block0.uly = block1.uly = block2.uly = blk.uly;
				
				//Fill in buffer blocks (to be read only)
				// Returned blocks may have different size and position
				block0 = (DataBlkInt) src.getInternCompData(block0, 0);
				data0 = (int[]) block0.Data;
				block1 = (DataBlkInt) src.getInternCompData(block1, 1);
				data1 = (int[]) block1.Data;
				block2 = (DataBlkInt) src.getInternCompData(block2, 2);
				bdata = (int[]) block2.Data;
				
				// Set the progressiveness of the output data
				blk.progressive = block0.progressive || block1.progressive || block2.progressive;
				blk.offset = 0;
				blk.scanw = w;
				
				//Perform conversion
				
				// Initialize general indexes
				k = w * h - 1;
				k0 = block0.offset + (h - 1) * block0.scanw + w - 1;
				k1 = block1.offset + (h - 1) * block1.scanw + w - 1;
				k2 = block2.offset + (h - 1) * block2.scanw + w - 1;
				
				switch (c)
				{
					
					case 0:  //RGB to Yr conversion
						for (i = h - 1; i >= 0; i--)
						{
							for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
							{
								// Use int arithmetic with 12 fractional bits
								// and rounding
								outdata[k] = (data0[k] + 2 * data1[k] + bdata[k]) >> 2; // Same as / 4
							}
							// Jump to beggining of previous line in input
							k0 -= (block0.scanw - w);
							k1 -= (block1.scanw - w);
							k2 -= (block2.scanw - w);
						}
						break;
					
					
					case 1:  //RGB to Ur conversion
						for (i = h - 1; i >= 0; i--)
						{
							for (mink = k - w; k > mink; k--, k1--, k2--)
							{
								// Use int arithmetic with 12 fractional bits
								// and rounding
								outdata[k] = bdata[k2] - data1[k1];
							}
							// Jump to beggining of previous line in input
							k1 -= (block1.scanw - w);
							k2 -= (block2.scanw - w);
						}
						break;
					
					
					case 2:  //RGB to Vr conversion
						for (i = h - 1; i >= 0; i--)
						{
							for (mink = k - w; k > mink; k--, k0--, k1--)
							{
								// Use int arithmetic with 12 fractional bits
								// and rounding
								outdata[k] = data0[k0] - data1[k1];
							}
							// Jump to beggining of previous line in input
							k0 -= (block0.scanw - w);
							k1 -= (block1.scanw - w);
						}
						break;
					}
			}
			else if (c >= 3)
			{
				// Requesting a component which is not Y, Ur or Vr =>
				// just pass the data            
				return src.getInternCompData(blk, c);
			}
			else
			{
				// Requesting a non valid component index
				throw new System.ArgumentException();
			}
			return blk;
		}
 /// <summary> Returns, in the blk argument, a block of image data containing the
 /// specifed rectangular area, in the specified component. The data is
 /// returned, as a copy of the internal data, therefore the returned data
 /// can be modified "in place".
 ///
 /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
 /// and 'h' members of the 'blk' argument, relative to the current
 /// tile. These members are not modified by this method. The 'offset' of
 /// the returned data is 0, and the 'scanw' is the same as the block's
 /// width. See the 'DataBlk' class.
 ///
 /// <P>This method, in general, is less efficient than the
 /// 'getInternCompData()' method since, in general, it copies the
 /// data. However if the array of returned data is to be modified by the
 /// caller then this method is preferable.
 ///
 /// <P>If the data array in 'blk' is 'null', then a new one is created. If
 /// the data array is not 'null' then it is reused, and it must be large
 /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
 /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
 ///
 /// <P>The returned data may have its 'progressive' attribute set. In this
 /// case the returned data is only an approximation of the "final" data.
 ///
 /// </summary>
 /// <param name="blk">Its coordinates and dimensions specify the area to return,
 /// relative to the current tile. If it contains a non-null data array,
 /// then it must be large enough. If it contains a null data array a new
 /// one is created. Some fields in this object are modified to return the
 /// data.
 ///
 /// </param>
 /// <param name="c">The index of the component from which to get the data.
 ///
 /// </param>
 /// <returns> The requested DataBlk
 ///
 /// </returns>
 /// <seealso cref="getInternCompData">
 ///
 /// </seealso>
 public virtual DataBlk getCompData(DataBlk blk, int c)
 {
     return(imageData[c].getCompData(blk, compIdx[c]));
 }
Esempio n. 19
0
		/// <summary> Apply forward irreversible component transformation to obtain requested
		/// component from specified block of data. Whatever the type of requested
		/// DataBlk, it always returns a DataBlkFloat.
		/// 
		/// </summary>
		/// <param name="blk">Determine the rectangular area to return 
		/// 
		/// </param>
		/// <param name="c">The index of the requested component
		/// 
		/// </param>
		/// <returns> Data of requested component
		/// 
		/// </returns>
		private DataBlk forwICT(DataBlk blk, int c)
		{
			int k, k0, k1, k2, mink, i;
			int w = blk.w; //width of output block
			int h = blk.h; //height of ouput block
			float[] outdata; //array of output data
			
			if (blk.DataType != DataBlk.TYPE_FLOAT)
			{
				if (outBlk == null || outBlk.DataType != DataBlk.TYPE_FLOAT)
				{
					outBlk = new DataBlkFloat();
				}
				outBlk.w = w;
				outBlk.h = h;
				outBlk.ulx = blk.ulx;
				outBlk.uly = blk.uly;
				blk = outBlk;
			}
			
			//Reference to output block data array
			outdata = (float[]) blk.Data;
			
			//Create data array of blk if necessary
			if (outdata == null || outdata.Length < w * h)
			{
				outdata = new float[h * w];
				blk.Data = outdata;
			}
			
			//If asking for Y, Cb or Cr do transform
			if (c >= 0 && c <= 2)
			{
				
				int[] data0, data1, data2; // input data arrays
				
				if (block0 == null)
				{
					block0 = new DataBlkInt();
				}
				if (block1 == null)
				{
					block1 = new DataBlkInt();
				}
				if (block2 == null)
				{
					block2 = new DataBlkInt();
				}
				block0.w = block1.w = block2.w = blk.w;
				block0.h = block1.h = block2.h = blk.h;
				block0.ulx = block1.ulx = block2.ulx = blk.ulx;
				block0.uly = block1.uly = block2.uly = blk.uly;
				
				// Returned blocks may have different size and position
				block0 = (DataBlkInt) src.getInternCompData(block0, 0);
				data0 = (int[]) block0.Data;
				block1 = (DataBlkInt) src.getInternCompData(block1, 1);
				data1 = (int[]) block1.Data;
				block2 = (DataBlkInt) src.getInternCompData(block2, 2);
				data2 = (int[]) block2.Data;
				
				// Set the progressiveness of the output data
				blk.progressive = block0.progressive || block1.progressive || block2.progressive;
				blk.offset = 0;
				blk.scanw = w;
				
				//Perform conversion
				
				// Initialize general indexes
				k = w * h - 1;
				k0 = block0.offset + (h - 1) * block0.scanw + w - 1;
				k1 = block1.offset + (h - 1) * block1.scanw + w - 1;
				k2 = block2.offset + (h - 1) * block2.scanw + w - 1;
				
				switch (c)
				{
					
					case 0: 
						//RGB to Y conversion
						for (i = h - 1; i >= 0; i--)
						{
							for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
							{
								outdata[k] = 0.299f * data0[k0] + 0.587f * data1[k1] + 0.114f * data2[k2];
							}
							// Jump to beggining of previous line in input
							k0 -= (block0.scanw - w);
							k1 -= (block1.scanw - w);
							k2 -= (block2.scanw - w);
						}
						break;
					
					
					case 1: 
						//RGB to Cb conversion
						for (i = h - 1; i >= 0; i--)
						{
							for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
							{
								outdata[k] = (- 0.16875f) * data0[k0] - 0.33126f * data1[k1] + 0.5f * data2[k2];
							}
							// Jump to beggining of previous line in input
							k0 -= (block0.scanw - w);
							k1 -= (block1.scanw - w);
							k2 -= (block2.scanw - w);
						}
						break;
					
					
					case 2: 
						//RGB to Cr conversion
						for (i = h - 1; i >= 0; i--)
						{
							for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
							{
								outdata[k] = 0.5f * data0[k0] - 0.41869f * data1[k1] - 0.08131f * data2[k2];
							}
							// Jump to beggining of previous line in input
							k0 -= (block0.scanw - w);
							k1 -= (block1.scanw - w);
							k2 -= (block2.scanw - w);
						}
						break;
					}
			}
			else if (c >= 3)
			{
				// Requesting a component which is not Y, Cb or Cr =>
				// just pass the data
				
				// Variables
				DataBlkInt indb = new DataBlkInt(blk.ulx, blk.uly, w, h);
				int[] indata; // input data array
				
				// Get the input data
				// (returned block may be larger than requested one)
				src.getInternCompData(indb, c);
				indata = (int[]) indb.Data;
				
				// Copy the data converting from int to float
				k = w * h - 1;
				k0 = indb.offset + (h - 1) * indb.scanw + w - 1;
				for (i = h - 1; i >= 0; i--)
				{
					for (mink = k - w; k > mink; k--, k0--)
					{
						//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'"
						outdata[k] = (float) indata[k0];
					}
					// Jump to beggining of next line in input
					k0 += indb.w - w;
				}
				
				// Set the progressivity
				blk.progressive = indb.progressive;
				blk.offset = 0;
				blk.scanw = w;
				return blk;
			}
			else
			{
				// Requesting a non valid component index
				throw new System.ArgumentException();
			}
			return blk;
		}
Esempio n. 20
0
		/// <summary> Performs the 2D forward wavelet transform on a subband of the initial
		/// band. This method will successively perform 1D filtering steps on all
		/// lines and then all columns of the subband. In this class only filters
		/// with floating point implementations can be used.
		/// 
		/// </summary>
		/// <param name="band">The band containing the float data to decompose
		/// 
		/// </param>
		/// <param name="subband">The structure containing the coordinates of the subband
		/// in the whole band to decompose.
		/// 
		/// </param>
		/// <param name="c">The index of the current component to decompose
		/// 
		/// </param>
		private void  wavelet2DDecomposition(DataBlk band, SubbandAn subband, int c)
		{
			
			int ulx, uly, w, h;
			int band_w, band_h;
			
			// If subband is empty (i.e. zero size) nothing to do
			if (subband.w == 0 || subband.h == 0)
			{
				return ;
			}
			
			ulx = subband.ulx;
			uly = subband.uly;
			w = subband.w;
			h = subband.h;
			band_w = getTileCompWidth(tIdx, c);
			band_h = getTileCompHeight(tIdx, c);
			
			if (intData)
			{
				//Perform the decompositions if the filter is implemented with an
				//integer arithmetic.
				int i, j;
				int offset;
				int[] tmpVector = new int[System.Math.Max(w, h)];
				int[] data = ((DataBlkInt) band).DataInt;
				
				//Perform the vertical decomposition
				if (subband.ulcy % 2 == 0)
				{
					// Even start index => use LPF
					for (j = 0; j < w; j++)
					{
						offset = uly * band_w + ulx + j;
						for (i = 0; i < h; i++)
							tmpVector[i] = data[offset + (i * band_w)];
						subband.vFilter.analyze_lpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + ((h + 1) / 2) * band_w, band_w);
					}
				}
				else
				{
					// Odd start index => use HPF
					for (j = 0; j < w; j++)
					{
						offset = uly * band_w + ulx + j;
						for (i = 0; i < h; i++)
							tmpVector[i] = data[offset + (i * band_w)];
						subband.vFilter.analyze_hpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + (h / 2) * band_w, band_w);
					}
				}
				
				//Perform the horizontal decomposition.
				if (subband.ulcx % 2 == 0)
				{
					// Even start index => use LPF
					for (i = 0; i < h; i++)
					{
						offset = (uly + i) * band_w + ulx;
						for (j = 0; j < w; j++)
							tmpVector[j] = data[offset + j];
						subband.hFilter.analyze_lpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + (w + 1) / 2, 1);
					}
				}
				else
				{
					// Odd start index => use HPF
					for (i = 0; i < h; i++)
					{
						offset = (uly + i) * band_w + ulx;
						for (j = 0; j < w; j++)
							tmpVector[j] = data[offset + j];
						subband.hFilter.analyze_hpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + w / 2, 1);
					}
				}
			}
			else
			{
				//Perform the decompositions if the filter is implemented with a
				//float arithmetic.
				int i, j;
				int offset;
				float[] tmpVector = new float[System.Math.Max(w, h)];
				float[] data = ((DataBlkFloat) band).DataFloat;
				
				//Perform the vertical decomposition.
				if (subband.ulcy % 2 == 0)
				{
					// Even start index => use LPF
					for (j = 0; j < w; j++)
					{
						offset = uly * band_w + ulx + j;
						for (i = 0; i < h; i++)
							tmpVector[i] = data[offset + (i * band_w)];
						subband.vFilter.analyze_lpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + ((h + 1) / 2) * band_w, band_w);
					}
				}
				else
				{
					// Odd start index => use HPF
					for (j = 0; j < w; j++)
					{
						offset = uly * band_w + ulx + j;
						for (i = 0; i < h; i++)
							tmpVector[i] = data[offset + (i * band_w)];
						subband.vFilter.analyze_hpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset + (h / 2) * band_w, band_w);
					}
				}
				//Perform the horizontal decomposition.
				if (subband.ulcx % 2 == 0)
				{
					// Even start index => use LPF
					for (i = 0; i < h; i++)
					{
						offset = (uly + i) * band_w + ulx;
						for (j = 0; j < w; j++)
							tmpVector[j] = data[offset + j];
						subband.hFilter.analyze_lpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + (w + 1) / 2, 1);
					}
				}
				else
				{
					// Odd start index => use HPF
					for (i = 0; i < h; i++)
					{
						offset = (uly + i) * band_w + ulx;
						for (j = 0; j < w; j++)
							tmpVector[j] = data[offset + j];
						subband.hFilter.analyze_hpf(tmpVector, 0, w, 1, data, offset, 1, data, offset + w / 2, 1);
					}
				}
			}
		}
Esempio n. 21
0
        public DataBlk getInternCompData(DataBlk blk, int c)
        {
            if (c < 0 || c >= this.nc)
            {
                throw new ArgumentOutOfRangeException("c");
            }

            var data = new int[blk.w * blk.h];
            for (int y = blk.uly, k = 0; y < blk.uly + blk.h; ++y)
            {
                for (int x = blk.ulx, xy = blk.uly * this.w + blk.ulx; x < blk.ulx + blk.w; ++x, ++k, ++xy)
                {
                    data[k] = this.comps[c][xy];
                }
            }

            blk.offset = 0;
            blk.scanw = blk.w;
            blk.progressive = false;
            blk.Data = data;

            return blk;
        }
Esempio n. 22
0
		/// <summary> Returns, in the blk argument, a block of image data containing the
		/// specifed rectangular area, in the specified component, using the
		/// 'transfer type' defined in the block given as argument. The data is
		/// returned, as a reference to the internal data, if any, instead of as a
		/// copy, therefore the returned data should not be modified.
		/// 
		/// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
		/// and 'h' members of the 'blk' argument, relative to the current
		/// tile. These members are not modified by this method. The 'offset' and
		/// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class.
		/// 
		/// <P> If source data and expected data (blk) are using the same type,
		/// block returned without any modification. If not appropriate cast is
		/// used.
		/// 
		/// <P>This method, in general, is more efficient than the 'getCompData()'
		/// method since it may not copy the data. However if the array of returned
		/// data is to be modified by the caller then the other method is probably
		/// preferable.
		/// 
		/// <P>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one
		/// is created if necessary. The implementation of this interface may
		/// choose to return the same array or a new one, depending on what is more
		/// efficient. Therefore, the data array in <tt>blk</tt> prior to the
		/// method call should not be considered to contain the returned data, a
		/// new array may have been created. Instead, get the array from
		/// <tt>blk</tt> after the method has returned.
		/// 
		/// <P>The returned data may have its 'progressive' attribute set. In this
		/// case the returned data is only an approximation of the "final" data.
		/// 
		/// </summary>
		/// <param name="blk">Its coordinates and dimensions specify the area to return,
		/// relative to the current tile. Some fields in this object are modified
		/// to return the data.
		/// 
		/// </param>
		/// <param name="c">The index of the component from which to get the data.
		/// 
		/// </param>
		/// <returns> The requested DataBlk
		/// 
		/// </returns>
		/// <seealso cref="getCompData">
		/// 
		/// </seealso>
		public DataBlk getInternCompData(DataBlk blk, int c)
		{
			return getData(blk, c, true);
		}
Esempio n. 23
0
        /// <summary> Returns a block of image data containing the specifed rectangular area,
        /// in the specified component, as a reference to the internal buffer (see
        /// below). The rectangular area is specified by the coordinates and
        /// dimensions of the 'blk' object.
        /// 
        /// <p>The area to return is specified by the 'ulx', 'uly', 'w' and 'h'
        /// members of the 'blk' argument. These members are not modified by this
        /// method.</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>
        /// 
        /// <p>The returned data has its 'progressive' attribute unset
        /// (i.e. false).</p>
        /// 
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to return.
        /// 
        /// </param>
        /// <param name="c">The index of the component from which to get the data.
        /// 
        /// </param>
        /// <returns> The requested DataBlk
        /// 
        /// </returns>
        /// <seealso cref="getInternCompData">
        /// 
        /// </seealso>
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            int tIdx = TileIdx;
            if (src.getSynSubbandTree(tIdx, c).HorWFilter == null)
            {
                dtype = DataBlk.TYPE_INT;
            }
            else
            {
                dtype = src.getSynSubbandTree(tIdx, c).HorWFilter.DataType;
            }

            //If the source image has not been decomposed
            if (reconstructedComps[c] == null)
            {
                //Allocate component data buffer
                switch (dtype)
                {

                    case DataBlk.TYPE_FLOAT:
                        reconstructedComps[c] = new DataBlkFloat(0, 0, getTileCompWidth(tIdx, c), getTileCompHeight(tIdx, c));
                        break;

                    case DataBlk.TYPE_INT:
                        reconstructedComps[c] = new DataBlkInt(0, 0, getTileCompWidth(tIdx, c), getTileCompHeight(tIdx, c));
                        break;
                    }
                //Reconstruct source image
                waveletTreeReconstruction(reconstructedComps[c], src.getSynSubbandTree(tIdx, c), c);
            }

            if (blk.DataType != dtype)
            {
                if (dtype == DataBlk.TYPE_INT)
                {
                    blk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                }
                else
                {
                    blk = new DataBlkFloat(blk.ulx, blk.uly, blk.w, blk.h);
                }
            }
            // Set the reference to the internal buffer
            blk.Data = reconstructedComps[c].Data;
            blk.offset = reconstructedComps[c].w * blk.uly + blk.ulx;
            blk.scanw = reconstructedComps[c].w;
            blk.progressive = false;
            return blk;
        }
Esempio n. 24
0
 public DataBlk getCompData(DataBlk blk, int c)
 {
     var newBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
     return this.getInternCompData(newBlk, c);
 }
Esempio n. 25
0
		/// <summary> Performs the cleanup pass on the specified data and bit-plane. It
		/// decodes all insignificant samples which have its "visited" state bit
		/// off, using the ZC, SC, and RLC primitives. It toggles the "visited"
		/// state bit to 0 (off) for all samples in the code-block.
		/// 
		/// <P>This method also checks for segmentation markers if those are
		/// present and returns true if an error is detected, or false
		/// otherwise. If an error is detected it measn that the bit stream
		/// contains some erroneous bit that have led to the decoding of incorrect
		/// data. This data affects the whole last decoded bit-plane
		/// (i.e. 'bp'). If 'true' is returned the 'conceal' method should be
		/// called and no more passes should be decoded for this code-block's bit
		/// stream.
		/// 
		/// </summary>
		/// <param name="cblk">The code-block data to code
		/// 
		/// </param>
		/// <param name="mq">The MQ-coder to use
		/// 
		/// </param>
		/// <param name="bp">The bit-plane to decode
		/// 
		/// </param>
		/// <param name="state">The state information for the code-block
		/// 
		/// </param>
		/// <param name="zc_lut">The ZC lookup table to use in ZC.
		/// 
		/// </param>
		/// <param name="isterm">If this pass has been terminated. If the pass has been
		/// terminated it can be used to check error resilience.
		/// 
		/// </param>
		/// <returns> True if an error was detected in the bit stream, false
		/// otherwise.
		/// 
		/// </returns>
		private bool cleanuppass(DataBlk cblk, MQDecoder mq, int bp, int[] state, int[] zc_lut, bool isterm)
		{
			int j, sj; // The state index for line and stripe
			int k, sk; // The data index for line and stripe
			int dscanw; // The data scan-width
			int sscanw; // The state scan-width
			int jstep; // Stripe to stripe step for 'sj'
			int kstep; // Stripe to stripe step for 'sk'
			int stopsk; // The loop limit on the variable sk
			int csj; // Local copy (i.e. cached) of 'state[j]'
			int setmask; // The mask to set current and lower bit-planes to 1/2
			// approximation
			int sym; // The decoded symbol
			int rlclen; // Length of RLC
			int ctxt; // The context to use
			int[] data; // The data buffer
			int s; // The stripe index
			bool causal; // Flag to indicate if stripe-causal context
			// formation is to be used
			int nstripes; // The number of stripes in the code-block
			int sheight; // Height of the current stripe
			int off_ul, off_ur, off_dr, off_dl; // offsets
			bool error; // The error condition
			
			// Initialize local variables
			dscanw = cblk.scanw;
			sscanw = cblk.w + 2;
			jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - cblk.w;
			kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - cblk.w;
			setmask = (3 << bp) >> 1;
			data = (int[]) cblk.Data;
			nstripes = (cblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
			causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0;
			
			// Pre-calculate offsets in 'state' for diagonal neighbors
			off_ul = - sscanw - 1; // up-left
			off_ur = - sscanw + 1; // up-right
			off_dr = sscanw + 1; // down-right
			off_dl = sscanw - 1; // down-left
			
			// Decode stripe by stripe
			sk = cblk.offset;
			sj = sscanw + 1;
			for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
			{
				sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:cblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
				stopsk = sk + cblk.w;
				// Scan by set of 1 stripe column at a time
				for (; sk < stopsk; sk++, sj++)
				{
					// Start column
					j = sj;
					csj = state[j];
					{
						// Check for RLC: if all samples are not significant, not
						// visited and do not have a non-zero context, and column
						// is full height, we do RLC.
						if (csj == 0 && state[j + sscanw] == 0 && sheight == CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT)
						{
							if (mq.decodeSymbol(RLC_CTXT) != 0)
							{
								// run-length is significant, decode length
								rlclen = mq.decodeSymbol(UNIF_CTXT) << 1;
								rlclen |= mq.decodeSymbol(UNIF_CTXT);
								// Set 'k' and 'j' accordingly
								k = sk + rlclen * dscanw;
								if (rlclen > 1)
								{
									j += sscanw;
									csj = state[j];
								}
							}
							else
							{
								// RLC is insignificant
								// Goto next column
								continue;
							}
							// We just decoded the length of a significant RLC
							// and a sample became significant
							// Use sign coding
							if ((rlclen & 0x01) == 0)
							{
								// Sample that became significant is first row of
								// its column half
								ctxt = SC_LUT[(csj >> SC_SHIFT_R1) & SC_MASK];
								sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
								// Update the data
								data[k] = (sym << 31) | setmask;
								// Update state information (significant bit,
								// visited bit, neighbor significant bit of
								// neighbors, non zero context of neighbors, sign
								// of neighbors)
								if (rlclen != 0 || !causal)
								{
									// If in causal mode do not change
									// contexts of previous stripe.
									state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
									state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
								}
								// Update sign state information of neighbors
								if (sym != 0)
								{
									csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
									if (rlclen != 0 || !causal)
									{
										// If in causal mode do not change
										// contexts of previous stripe.
										state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
									}
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
								}
								else
								{
									csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
									if (rlclen != 0 || !causal)
									{
										// If in causal mode do not change
										// contexts of previous stripe.
										state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
									}
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
								}
								// Changes to csj are saved later
								if ((rlclen >> 1) != 0)
								{
									// Sample that became significant is in
									// bottom half of column => jump to bottom
									// half
									//UPGRADE_NOTE: Labeled break statement was changed to a goto statement. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1012'"
									goto top_half_brk;
								}
								// Otherwise sample that became significant is in
								// top half of column => continue on top half
							}
							else
							{
								// Sample that became significant is second row of
								// its column half
								ctxt = SC_LUT[(csj >> SC_SHIFT_R2) & SC_MASK];
								sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
								// Update the data
								data[k] = (sym << 31) | setmask;
								// Update state information (significant bit,
								// neighbor significant bit of neighbors, non zero
								// context of neighbors, sign of neighbors)
								state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
								state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
								// Update sign state information of neighbors
								if (sym != 0)
								{
									csj |= STATE_SIG_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
									state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
								}
								else
								{
									csj |= STATE_SIG_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
									state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
								}
								// Save changes to csj
								state[j] = csj;
								if ((rlclen >> 1) != 0)
								{
									// Sample that became significant is in bottom
									// half of column => we're done with this
									// column
									continue;
								}
								// Otherwise sample that became significant is in
								// top half of column => we're done with top
								// column
								j += sscanw;
								csj = state[j];
								//UPGRADE_NOTE: Labeled break statement was changed to a goto statement. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1012'"
								goto top_half_brk;
							}
						}
						// Do half top of column
						// If any of the two samples is not significant and has
						// not been visited in the current bit-plane we can not
						// skip them
						if ((((csj >> 1) | csj) & VSTD_MASK_R1R2) != VSTD_MASK_R1R2)
						{
							k = sk;
							// Scan first row
							if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == 0)
							{
								// Use zero coding
								if (mq.decodeSymbol(zc_lut[csj & ZC_MASK]) != 0)
								{
									// Became significant
									// Use sign coding
									ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R1)) & SC_MASK];
									sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
									// Update the data
									data[k] = (sym << 31) | setmask;
									// Update state information (significant bit,
									// visited bit, neighbor significant bit of
									// neighbors, non zero context of neighbors,
									// sign of neighbors)
									if (!causal)
									{
										// If in causal mode do not change
										// contexts of previous stripe.
										state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
										state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
									}
									// Update sign state information of neighbors
									if (sym != 0)
									{
										csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
										if (!causal)
										{
											// If in causal mode do not change
											// contexts of previous stripe.
											state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
										}
										state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
										state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
									}
									else
									{
										csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
										if (!causal)
										{
											// If in causal mode do not change
											// contexts of previous stripe.
											state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
										}
										state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
										state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
									}
								}
							}
							if (sheight < 2)
							{
								csj &= ~ (STATE_VISITED_R1 | STATE_VISITED_R2);
								state[j] = csj;
								continue;
							}
							// Scan second row
							if ((csj & (STATE_SIG_R2 | STATE_VISITED_R2)) == 0)
							{
								k += dscanw;
								// Use zero coding
								if (mq.decodeSymbol(zc_lut[(SupportClass.URShift(csj, STATE_SEP)) & ZC_MASK]) != 0)
								{
									// Became significant
									// Use sign coding
									ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
									sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
									// Update the data
									data[k] = (sym << 31) | setmask;
									// Update state information (significant bit,
									// visited bit, neighbor significant bit of
									// neighbors, non zero context of neighbors,
									// sign of neighbors)
									state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
									state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
									// Update sign state information of neighbors
									if (sym != 0)
									{
										csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
										state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
										state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
										state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
									}
									else
									{
										csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
										state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
										state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
										state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
									}
								}
							}
						}
						csj &= ~ (STATE_VISITED_R1 | STATE_VISITED_R2);
						state[j] = csj;
						// Do half bottom of column
						if (sheight < 3)
							continue;
						j += sscanw;
						csj = state[j];
					}
					//UPGRADE_NOTE: Label 'top_half_brk' was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1011'"

top_half_brk: ;
					 // end of 'top_half' block
					// If any of the two samples is not significant and has
					// not been visited in the current bit-plane we can not
					// skip them
					if ((((csj >> 1) | csj) & VSTD_MASK_R1R2) != VSTD_MASK_R1R2)
					{
						k = sk + (dscanw << 1);
						// Scan first row
						if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == 0)
						{
							// Use zero coding
							if (mq.decodeSymbol(zc_lut[csj & ZC_MASK]) != 0)
							{
								// Became significant
								// Use sign coding
								ctxt = SC_LUT[(csj >> SC_SHIFT_R1) & SC_MASK];
								sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
								// Update the data
								data[k] = (sym << 31) | setmask;
								// Update state information (significant bit,
								// visited bit, neighbor significant bit of
								// neighbors, non zero context of neighbors,
								// sign of neighbors)
								state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
								state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
								// Update sign state information of neighbors
								if (sym != 0)
								{
									csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
									state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
								}
								else
								{
									csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
									state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
								}
							}
						}
						if (sheight < 4)
						{
							csj &= ~ (STATE_VISITED_R1 | STATE_VISITED_R2);
							state[j] = csj;
							continue;
						}
						// Scan second row
						if ((csj & (STATE_SIG_R2 | STATE_VISITED_R2)) == 0)
						{
							k += dscanw;
							// Use zero coding
							if (mq.decodeSymbol(zc_lut[(SupportClass.URShift(csj, STATE_SEP)) & ZC_MASK]) != 0)
							{
								// Became significant
								// Use sign coding
								ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
								sym = mq.decodeSymbol(ctxt & SC_LUT_MASK) ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
								// Update the data
								data[k] = (sym << 31) | setmask;
								// Update state information (significant bit,
								// visited bit, neighbor significant bit of
								// neighbors, non zero context of neighbors,
								// sign of neighbors)
								state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
								state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
								// Update sign state information of neighbors
								if (sym != 0)
								{
									csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
									state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
								}
								else
								{
									csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
									state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
									state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
									state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
								}
							}
						}
					}
					csj &= ~ (STATE_VISITED_R1 | STATE_VISITED_R2);
					state[j] = csj;
				}
			}
			
			// Decode segment symbol if we need to
			if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS) != 0)
			{
				sym = mq.decodeSymbol(UNIF_CTXT) << 3;
				sym |= mq.decodeSymbol(UNIF_CTXT) << 2;
				sym |= mq.decodeSymbol(UNIF_CTXT) << 1;
				sym |= mq.decodeSymbol(UNIF_CTXT);
				// Set error condition accordingly
				error = sym != SEG_SYMBOL;
			}
			else
			{
				// We can not detect any errors
				error = false;
			}
			
			// Check the error resilience termination
			if (isterm && (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0)
			{
				error = mq.checkPredTerm();
			}
			
			// Reset the MQ context states if we need to
			if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ) != 0)
			{
				mq.resetCtxts();
			}
			
			// Return error condition
			return error;
		}
Esempio n. 26
0
        /// <summary> Returns a block of image data containing the specifed rectangular area,
        /// in the specified component, as a copy (see below). The rectangular area
        /// is specified by the coordinates and dimensions of the 'blk' object.
        /// 
        /// <p>The area to return is specified by the 'ulx', 'uly', 'w' and 'h'
        /// members of the 'blk' argument. These members are not modified by this
        /// method.</p>
        /// 
        /// <p>The data returned by this method is always a copy of the internal
        /// data of this object, if any, and it can be modified "in place" without
        /// any problems after being returned. The 'offset' of the returned data is
        /// 0, and the 'scanw' is the same as the block's width. See the 'DataBlk'
        /// class.</p>
        /// 
        /// <p>If the data array in 'blk' is <tt>null</tt>, then a new one is
        /// created. If the data array is not <tt>null</tt> then it must be big
        /// enough to contain the requested area.</p>
        /// 
        /// <p>The returned data always has its 'progressive' attribute unset (i.e
        /// false)</p>
        /// 
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. If it contains a non-null data array, then it must be large
        /// enough. If it contains a null data array a new one is created. The
        /// fields in this object are modified to return the data.
        /// 
        /// </param>
        /// <param name="c">The index of the component from which to get the data.
        /// 
        /// </param>
        /// <returns> The requested DataBlk
        /// 
        /// </returns>
        /// <seealso cref="getCompData">
        /// 
        /// </seealso>
        public override DataBlk getCompData(DataBlk blk, int c)
        {
            //int j;
            System.Object dst_data; // src_data removed
            int[] dst_data_int; // src_data_int removed
            float[] dst_data_float; // src_data_float removed

            // To keep compiler happy
            dst_data = null;

            // Ensure output buffer
            switch (blk.DataType)
            {

                case DataBlk.TYPE_INT:
                    dst_data_int = (int[]) blk.Data;
                    if (dst_data_int == null || dst_data_int.Length < blk.w * blk.h)
                    {
                        dst_data_int = new int[blk.w * blk.h];
                    }
                    dst_data = dst_data_int;
                    break;

                case DataBlk.TYPE_FLOAT:
                    dst_data_float = (float[]) blk.Data;
                    if (dst_data_float == null || dst_data_float.Length < blk.w * blk.h)
                    {
                        dst_data_float = new float[blk.w * blk.h];
                    }
                    dst_data = dst_data_float;
                    break;
                }

            // Use getInternCompData() to get the data, since getInternCompData()
            // returns reference to internal buffer, we must copy it.
            blk = getInternCompData(blk, c);

            // Copy the data
            blk.Data = dst_data;
            blk.offset = 0;
            blk.scanw = blk.w;
            return blk;
        }
Esempio n. 27
0
		/// <summary> Returns, in the blk argument, the block of image data containing the
		/// specifed rectangular area, in the specified component. The data is
		/// returned, as a reference to the internal data, if any, instead of as a
		/// copy, therefore the returned data should not be modified.
		/// 
		/// <p>After being read the coefficients are level shifted by subtracting
		/// 2^(nominal bit range - 1)<p>
		/// 
		/// <p>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
		/// and 'h' members of the 'blk' argument, relative to the current
		/// tile. These members are not modified by this method. The 'offset' and
		/// 'scanw' of the returned data can be arbitrary. See the 'DataBlk'
		/// class.</p>
		/// 
		/// <p>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one
		/// is created if necessary. The implementation of this interface may
		/// choose to return the same array or a new one, depending on what is more
		/// efficient. Therefore, the data array in <tt>blk</tt> prior to the
		/// method call should not be considered to contain the returned data, a
		/// new array may have been created. Instead, get the array from
		/// <tt>blk</tt> after the method has returned.</p>
		/// 
		/// <p>The returned data always has its 'progressive' attribute unset
		/// (i.e. false).</p>
		/// 
		/// <p>When an I/O exception is encountered the JJ2KExceptionHandler is
		/// used. The exception is passed to its handleException method. The action
		/// that is taken depends on the action that has been registered in
		/// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.</p>
		/// 
		/// </summary>
		/// <param name="blk">Its coordinates and dimensions specify the area to
		/// return. Some fields in this object are modified to return the data.
		/// 
		/// </param>
		/// <param name="c">The index of the component from which to get the data. Only 0
		/// is valid.
		/// 
		/// </param>
		/// <returns> The requested DataBlk
		/// 
		/// </returns>
		/// <seealso cref="getCompData">
		/// </seealso>
		/// <seealso cref="JJ2KExceptionHandler">
		/// 
		/// </seealso>
		public override DataBlk getInternCompData(DataBlk blk, int c)
		{
			int k, j, i, mi; // counters
			int levShift = 1 << (bitDepth - 1);
			
			// Check component index
			if (c != 0)
				throw new System.ArgumentException();
			
			// Check type of block provided as an argument
			if (blk.DataType != DataBlk.TYPE_INT)
			{
				if (intBlk == null)
					intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
				else
				{
					intBlk.ulx = blk.ulx;
					intBlk.uly = blk.uly;
					intBlk.w = blk.w;
					intBlk.h = blk.h;
				}
				blk = intBlk;
			}
			
			// Get data array
			int[] barr = (int[]) blk.Data;
			if (barr == null || barr.Length < blk.w * blk.h * packBytes)
			{
				barr = new int[blk.w * blk.h];
				blk.Data = barr;
			}
			
			int paddingLength = (32 - bitDepth);
			if (buf == null || buf.Length < packBytes * blk.w)
			{
				buf = new byte[packBytes * blk.w];
			}
			try
			{
				switch (packBytes)
				{
					
					// Switch between one of the 3 byte packet type
					case 1:  // Samples packed into 1 byte
						// Read line by line
						mi = blk.uly + blk.h;
						if (isSigned)
						{
							for (i = blk.uly; i < mi; i++)
							{
								// Reposition in input
								in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin);
								in_Renamed.Read(buf, 0, blk.w);
								for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; k--)
									barr[k] = (((buf[j--] & 0xFF) << paddingLength) >> paddingLength);
							}
						}
						else
						{
							// Not signed
							for (i = blk.uly; i < mi; i++)
							{
								// Reposition in input
								in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin);
								in_Renamed.Read(buf, 0, blk.w);
								for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; k--)
									barr[k] = (SupportClass.URShift(((buf[j--] & 0xFF) << paddingLength), paddingLength)) - levShift;
							}
						}
						break;
					
					
					case 2:  // Samples packed into 2 bytes
						// Read line by line
						mi = blk.uly + blk.h;
						if (isSigned)
						{
							for (i = blk.uly; i < mi; i++)
							{
								// Reposition in input
								in_Renamed.Seek(offset + 2 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin);
								in_Renamed.Read(buf, 0, blk.w << 1);
								switch (byteOrder)
								{
									
									case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN: 
										for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--)
										{
											barr[k] = ((((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength) >> paddingLength;
										}
										break;
									
									case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN: 
										for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--)
										{
											barr[k] = (((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8)) << paddingLength) >> paddingLength;
										}
										break;
									
									default: 
										throw new System.ApplicationException("Internal JJ2000 bug");
									
								}
							}
						}
						else
						{
							// If not signed
							for (i = blk.uly; i < mi; i++)
							{
								// Reposition in input
								in_Renamed.Seek(offset + 2 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin);
								in_Renamed.Read(buf, 0, blk.w << 1);
								switch (byteOrder)
								{
									
									case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN: 
										for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--)
										{
											barr[k] = (SupportClass.URShift(((((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength), paddingLength)) - levShift;
										}
										break;
									
									case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN: 
										for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--)
										{
											barr[k] = (SupportClass.URShift((((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8)) << paddingLength), paddingLength)) - levShift;
										}
										break;
									
									default: 
										throw new System.ApplicationException("Internal JJ2000 bug");
									
								}
							}
						}
						break;
					
					
					case 4:  // Samples packed into 4 bytes
						// Read line by line
						mi = blk.uly + blk.h;
						if (isSigned)
						{
							for (i = blk.uly; i < mi; i++)
							{
								// Reposition in input
								in_Renamed.Seek(offset + 4 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin);
								in_Renamed.Read(buf, 0, blk.w << 2);
								switch (byteOrder)
								{
									
									case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN: 
										for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--)
										{
											barr[k] = ((((buf[j--] & 0xFF) << 24) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength) >> paddingLength;
										}
										break;
									
									case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN: 
										for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--)
										{
											barr[k] = (((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 24)) << paddingLength) >> paddingLength;
										}
										break;
									
									default: 
										throw new System.ApplicationException("Internal JJ2000 bug");
									
								}
							}
						}
						else
						{
							for (i = blk.uly; i < mi; i++)
							{
								// Reposition in input
								in_Renamed.Seek(offset + 4 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin);
								in_Renamed.Read(buf, 0, blk.w << 2);
								switch (byteOrder)
								{
									
									case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN: 
										for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--)
										{
											barr[k] = (SupportClass.URShift(((((buf[j--] & 0xFF) << 24) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength), paddingLength)) - levShift;
										}
										break;
									
									case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN: 
										for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--)
										{
											barr[k] = (SupportClass.URShift((((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 24)) << paddingLength), paddingLength)) - levShift;
										}
										break;
									
									default: 
										throw new System.ApplicationException("Internal JJ2000 bug");
									
								}
							}
						}
						break;
					
					
					default: 
						throw new System.IO.IOException("PGX supports only bit-depth between" + " 1 and 31");
					
				}
			}
			catch (System.IO.IOException e)
			{
				JJ2KExceptionHandler.handleException(e);
			}
			
			// Turn off the progressive attribute
			blk.progressive = false;
			// Set buffer attributes
			blk.offset = 0;
			blk.scanw = blk.w;
			return blk;
		}
Esempio n. 28
0
        /// <summary> Performs the 2D inverse wavelet transform on a subband of the image, on
        /// the specified component. This method will successively perform 1D
        /// filtering steps on all columns and then all lines of the subband.
        /// 
        /// </summary>
        /// <param name="db">the buffer for the image/wavelet data.
        /// 
        /// </param>
        /// <param name="sb">The subband to reconstruct.
        /// 
        /// </param>
        /// <param name="c">The index of the component to reconstruct 
        /// 
        /// </param>
        private void wavelet2DReconstruction(DataBlk db, SubbandSyn sb, int c)
        {
            System.Object data;
            System.Object buf;
            int ulx, uly, w, h;
            int i, j, k;
            int offset;

            // If subband is empty (i.e. zero size) nothing to do
            if (sb.w == 0 || sb.h == 0)
            {
                return ;
            }

            data = db.Data;

            ulx = sb.ulx;
            uly = sb.uly;
            w = sb.w;
            h = sb.h;

            buf = null; // To keep compiler happy

            switch (sb.HorWFilter.DataType)
            {

                case DataBlk.TYPE_INT:
                    buf = new int[(w >= h)?w:h];
                    break;

                case DataBlk.TYPE_FLOAT:
                    buf = new float[(w >= h)?w:h];
                    break;
                }

            //Perform the horizontal reconstruction
            offset = (uly - db.uly) * db.w + ulx - db.ulx;
            if (sb.ulcx % 2 == 0)
            {
                // start index is even => use LPF
                for (i = 0; i < h; i++, offset += db.w)
                {
                    // CONVERSION PROBLEM?
                    Array.Copy((System.Array)data, offset, (System.Array)buf, 0, w);
                    sb.hFilter.synthetize_lpf(buf, 0, (w + 1) / 2, 1, buf, (w + 1) / 2, w / 2, 1, data, offset, 1);
                }
            }
            else
            {
                // start index is odd => use HPF
                for (i = 0; i < h; i++, offset += db.w)
                {
                    // CONVERSION PROBLEM?
                    Array.Copy((System.Array)data, offset, (System.Array)buf, 0, w);
                    sb.hFilter.synthetize_hpf(buf, 0, w / 2, 1, buf, w / 2, (w + 1) / 2, 1, data, offset, 1);
                }
            }

            //Perform the vertical reconstruction
            offset = (uly - db.uly) * db.w + ulx - db.ulx;
            switch (sb.VerWFilter.DataType)
            {

                case DataBlk.TYPE_INT:
                    int[] data_int, buf_int;
                    data_int = (int[]) data;
                    buf_int = (int[]) buf;
                    if (sb.ulcy % 2 == 0)
                    {
                        // start index is even => use LPF
                        for (j = 0; j < w; j++, offset++)
                        {
                            for (i = h - 1, k = offset + i * db.w; i >= 0; i--, k -= db.w)
                                buf_int[i] = data_int[k];
                            sb.vFilter.synthetize_lpf(buf, 0, (h + 1) / 2, 1, buf, (h + 1) / 2, h / 2, 1, data, offset, db.w);
                        }
                    }
                    else
                    {
                        // start index is odd => use HPF
                        for (j = 0; j < w; j++, offset++)
                        {
                            for (i = h - 1, k = offset + i * db.w; i >= 0; i--, k -= db.w)
                                buf_int[i] = data_int[k];
                            sb.vFilter.synthetize_hpf(buf, 0, h / 2, 1, buf, h / 2, (h + 1) / 2, 1, data, offset, db.w);
                        }
                    }
                    break;

                case DataBlk.TYPE_FLOAT:
                    float[] data_float, buf_float;
                    data_float = (float[]) data;
                    buf_float = (float[]) buf;
                    if (sb.ulcy % 2 == 0)
                    {
                        // start index is even => use LPF
                        for (j = 0; j < w; j++, offset++)
                        {
                            for (i = h - 1, k = offset + i * db.w; i >= 0; i--, k -= db.w)
                                buf_float[i] = data_float[k];
                            sb.vFilter.synthetize_lpf(buf, 0, (h + 1) / 2, 1, buf, (h + 1) / 2, h / 2, 1, data, offset, db.w);
                        }
                    }
                    else
                    {
                        // start index is odd => use HPF
                        for (j = 0; j < w; j++, offset++)
                        {
                            for (i = h - 1, k = offset + i * db.w; i >= 0; i--, k -= db.w)
                                buf_float[i] = data_float[k];
                            sb.vFilter.synthetize_hpf(buf, 0, h / 2, 1, buf, h / 2, (h + 1) / 2, 1, data, offset, db.w);
                        }
                    }
                    break;
                }
        }
 public abstract CSJ2K.j2k.image.DataBlk getCompData(CSJ2K.j2k.image.DataBlk param1, int param2);
Esempio n. 30
0
		/// <summary> Returns the specified code-block in the current tile for the specified
		/// component, as a copy (see below).
		/// 
		/// <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 is always a copy of the internal
		/// data of this object, if any, and it can be modified "in place" without
		/// any problems after being returned. The 'offset' of the returned data is
		/// 0, and the 'scanw' is the same as the code-block width. See the
		/// 'DataBlk' class.</p>
		/// 
		/// <p>The 'ulx' and 'uly' members of the returned 'DataBlk' object contain
		/// the coordinates of the top-left corner of the block, with respect to
		/// the tile, not the subband.</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 'c', or
		/// null if all code-blocks for the current tile have been returned.
		/// 
		/// </returns>
		/// <seealso cref="DataBlk">
		/// 
		/// </seealso>
		public virtual DataBlk getCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
		{
			return getInternCodeBlock(c, m, n, sb, cblk);
		}
Esempio n. 31
0
		/// <summary> Apply inverse component transformation associated with the current
		/// tile. If no component transformation has been requested by the user,
		/// data are not modified.
		/// 
		/// <P>This method calls the getInternCompData() method, but respects the
		/// definitions of the getCompData() method defined in the BlkImgDataSrc
		/// interface.
		/// 
		/// </summary>
		/// <param name="blk">Determines the rectangular area to return, and the
		/// data is returned in this object.
		/// 
		/// </param>
		/// <param name="c">Index of the output component.
		/// 
		/// </param>
		/// <returns> The requested DataBlk
		/// 
		/// </returns>
		/// <seealso cref="BlkImgDataSrc.getCompData">
		/// 
		/// </seealso>
		public virtual DataBlk getCompData(DataBlk blk, int c)
		{
			// If requesting a component whose index is greater than 3 or there is
			// no transform return a copy of data (getInternCompData returns the
			// actual data in those cases)
			if (c >= 3 || transfType == NONE || noCompTransf)
			{
				return src.getCompData(blk, c);
			}
			else
			{
				// We can use getInternCompData (since data is a copy anyways)
				return getInternCompData(blk, c);
			}
		}
Esempio n. 32
0
        /// <summary> Returns, in the blk argument, the block of image data containing the
        /// specifed rectangular area, in the specified component. The data is
        /// returned, as a reference to the internal data, if any, instead of as a
        /// copy, therefore the returned data should not be modified.
        /// 
        /// <P> After being read the coefficients are level shifted by subtracting
        /// 2^(nominal bit range - 1)
        /// 
        /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
        /// and 'h' members of the 'blk' argument, relative to the current
        /// tile. These members are not modified by this method. The 'offset' and
        /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class.
        /// 
        /// <P>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one
        /// is created if necessary. The implementation of this interface may
        /// choose to return the same array or a new one, depending on what is more
        /// efficient. Therefore, the data array in <tt>blk</tt> prior to the
        /// method call should not be considered to contain the returned data, a
        /// new array may have been created. Instead, get the array from
        /// <tt>blk</tt> after the method has returned.
        /// 
        /// <P>The returned data always has its 'progressive' attribute unset
        /// (i.e. false).
        /// 
        /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
        /// used. The exception is passed to its handleException method. The action
        /// that is taken depends on the action that has been registered in
        /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
        /// 
        /// <P>This method implements buffering for the 3 components: When the
        /// first one is asked, all the 3 components are read and stored until they
        /// are needed.
        /// 
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. Some fields in this object are modified to return the data.
        /// 
        /// </param>
        /// <param name="c">The index of the component from which to get the data. Only 0,
        /// 1 and 3 are valid.
        /// 
        /// </param>
        /// <returns> The requested DataBlk
        /// 
        /// </returns>
        /// <seealso cref="getCompData">
        /// 
        /// </seealso>
        /// <seealso cref="JJ2KExceptionHandler">
        /// 
        /// </seealso>
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            // Check component index
            if (c < 0 || c > 2)
                throw new System.ArgumentException();

            // Check type of block provided as an argument
            if (blk.DataType != DataBlk.TYPE_INT)
            {
                if (intBlk == null)
                    intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                else
                {
                    intBlk.ulx = blk.ulx;
                    intBlk.uly = blk.uly;
                    intBlk.w = blk.w;
                    intBlk.h = blk.h;
                }
                blk = intBlk;
            }

            // If asking a component for the first time for this block, read all of the components
            if ((barr == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h))
            {
                int i;
                int[] red, green, blue, alpha;
                int componentCount = (image.PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3;

                barr = new int[componentCount][];

                // Reset data arrays if needed
                if (barr[c] == null || barr[c].Length < blk.w * blk.h)
                {
                    barr[c] = new int[blk.w * blk.h];
                }
                blk.Data = barr[c];

                i = (c + 1) % 3;
                if (barr[i] == null || barr[i].Length < blk.w * blk.h)
                {
                    barr[i] = new int[blk.w * blk.h];
                }
                i = (c + 2) % 3;
                if (barr[i] == null || barr[i].Length < blk.w * blk.h)
                {
                    barr[i] = new int[blk.w * blk.h];
                }

                if (componentCount == 4)
                {
                    if (barr[3] == null || barr[3].Length < blk.w * blk.h)
                        barr[3] = new int[blk.w * blk.h];
                }

                // set attributes of the DataBlk used for buffering
                dbi.ulx = blk.ulx;
                dbi.uly = blk.uly;
                dbi.w = blk.w;
                dbi.h = blk.h;

                red = barr[0];
                green = barr[1];
                blue = barr[2];
                alpha = (componentCount == 4) ? barr[3] : null;

                Bitmap bitmap = (Bitmap)image;
                BitmapData data = bitmap.LockBits(new Rectangle(blk.ulx, blk.uly, blk.w, blk.h), ImageLockMode.ReadOnly,
                    (componentCount == 3) ? PixelFormat.Format24bppRgb : PixelFormat.Format32bppArgb);
                unsafe
                {
                    byte* ptr = (byte*)data.Scan0.ToPointer();
                    
                    int k = 0;
                    for (int j = 0; j < blk.w * blk.h; j++)
                    {
                        blue[k] = ((byte)*(ptr + 0) & 0xFF) - 128;
                        green[k] = ((byte)*(ptr + 1) & 0xFF) - 128;
                        red[k] = ((byte)*(ptr + 2) & 0xFF) - 128;
                        if (componentCount == 4)
                            alpha[k] = ((byte)*(ptr + 3) & 0xFF) - 128;

                        ++k;
                        ptr += 3;
                    }
                }
                bitmap.UnlockBits(data);

                barr[0] = red;
                barr[1] = green;
                barr[2] = blue;
                if (componentCount == 4)
                    barr[3] = alpha;

                // Set buffer attributes
                blk.Data = barr[c];
                blk.offset = 0;
                blk.scanw = blk.w;
            }
            else
            {
                //Asking for the 2nd or 3rd (or 4th) block component
                blk.Data = barr[c];
                blk.offset = (blk.ulx - dbi.ulx) * dbi.w + blk.ulx - dbi.ulx;
                blk.scanw = dbi.scanw;
            }

            // Turn off the progressive attribute
            blk.progressive = false;
            return blk;
        }
Esempio n. 33
0
		/// <summary> Apply the inverse component transformation associated with the current
		/// tile. If no component transformation has been requested by the user,
		/// data are not modified. Else, appropriate method is called (invRCT or
		/// invICT).
		/// 
		/// </summary>
		/// <seealso cref="invRCT">
		/// 
		/// </seealso>
		/// <seealso cref="invICT">
		/// 
		/// </seealso>
		/// <param name="blk">Determines the rectangular area to return.
		/// 
		/// </param>
		/// <param name="c">Index of the output component.
		/// 
		/// </param>
		/// <returns> The requested DataBlk
		/// 
		/// </returns>
		public virtual DataBlk getInternCompData(DataBlk blk, int c)
		{
			// if specified in the command line that no component transform should
			// be made, return original data
			if (noCompTransf)
				return src.getInternCompData(blk, c);
			
			switch (transfType)
			{
				
				case NONE: 
					return src.getInternCompData(blk, c);
				
				
				case INV_RCT: 
					return invRCT(blk, c);
				
				case INV_ICT: 
					return invICT(blk, c);
				
				default: 
					throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation");
				
			}
		}
Esempio n. 34
0
		/// <summary> Returns, in the blk argument, the block of image data containing the
		/// specifed rectangular area, in the specified component. The data is
		/// returned, as a reference to the internal data, if any, instead of as a
		/// copy, therefore the returned data should not be modified.
		/// 
		/// <P> After being read the coefficients are level shifted by subtracting
		/// 2^(nominal bit range - 1)
		/// 
		/// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
		/// and 'h' members of the 'blk' argument, relative to the current
		/// tile. These members are not modified by this method. The 'offset' and
		/// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class.
		/// 
		/// <P>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one
		/// is created if necessary. The implementation of this interface may
		/// choose to return the same array or a new one, depending on what is more
		/// efficient. Therefore, the data array in <tt>blk</tt> prior to the
		/// method call should not be considered to contain the returned data, a
		/// new array may have been created. Instead, get the array from
		/// <tt>blk</tt> after the method has returned.
		/// 
		/// <P>The returned data always has its 'progressive' attribute unset
		/// (i.e. false).
		/// 
		/// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
		/// used. The exception is passed to its handleException method. The action
		/// that is taken depends on the action that has been registered in
		/// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
		/// 
		/// </summary>
		/// <param name="blk">Its coordinates and dimensions specify the area to
		/// return. Some fields in this object are modified to return the data.
		/// 
		/// </param>
		/// <param name="c">The index of the component from which to get the data. Only 0
		/// is valid.
		/// 
		/// </param>
		/// <returns> The requested DataBlk
		/// 
		/// </returns>
		/// <seealso cref="getCompData">
		/// 
		/// </seealso>
		/// <seealso cref="JJ2KExceptionHandler">
		/// 
		/// </seealso>
		public override DataBlk getInternCompData(DataBlk blk, int c)
		{
			int k, j, i, mi;
			int[] barr;
			
			// Check component index
			if (c != 0)
				throw new System.ArgumentException();
			
			// Check type of block provided as an argument
			if (blk.DataType != DataBlk.TYPE_INT)
			{
				if (intBlk == null)
					intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
				else
				{
					intBlk.ulx = blk.ulx;
					intBlk.uly = blk.uly;
					intBlk.w = blk.w;
					intBlk.h = blk.h;
				}
				blk = intBlk;
			}
			
			// Get data array
			barr = (int[]) blk.Data;
			if (barr == null || barr.Length < blk.w * blk.h)
			{
				barr = new int[blk.w * blk.h];
				blk.Data = barr;
			}
			
			// Check line buffer
			if (buf == null || buf.Length < blk.w)
			{
				buf = new byte[blk.w];
			}
			
			try
			{
				// Read line by line
				mi = blk.uly + blk.h;
				for (i = blk.uly; i < mi; i++)
				{
					// Reposition in input
					in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin);
					in_Renamed.Read(buf, 0, blk.w);
					for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; j--, k--)
					{
						barr[k] = (((int) buf[j]) & 0xFF) - DC_OFFSET;
					}
				}
			}
			catch (System.IO.IOException e)
			{
				JJ2KExceptionHandler.handleException(e);
			}
			
			// Turn off the progressive attribute
			blk.progressive = false;
			// Set buffer attributes
			blk.offset = 0;
			blk.scanw = blk.w;
			return blk;
		}
Esempio n. 35
0
		/// <summary> Apply inverse component transformation to obtain requested component
		/// from specified block of data. Whatever the type of requested DataBlk,
		/// it always returns a DataBlkInt.
		/// 
		/// </summary>
		/// <param name="blk">Determine the rectangular area to return 
		/// 
		/// </param>
		/// <param name="c">The index of the requested component
		/// 
		/// </param>
		/// <returns> Data of requested component
		/// 
		/// </returns>
		private DataBlk invRCT(DataBlk blk, int c)
		{
			// If the component number is three or greater, return original data
			if (c >= 3 && c < NumComps)
			{
				// Requesting a component whose index is greater than 3
				return src.getInternCompData(blk, c);
			}
			// If asking a component for the first time for this block,
			// do transform for the 3 components
			else if ((outdata[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h))
			{
				int k, k0, k1, k2, mink, i;
				int w = blk.w; //width of output block
				int h = blk.h; //height of ouput block
				
				//Reference to output block data array
				outdata[c] = (int[]) blk.Data;
				
				//Create data array of blk if necessary
				if (outdata[c] == null || outdata[c].Length != h * w)
				{
					outdata[c] = new int[h * w];
					blk.Data = outdata[c];
				}
				
				outdata[(c + 1) % 3] = new int[outdata[c].Length];
				outdata[(c + 2) % 3] = new int[outdata[c].Length];
				
				if (block0 == null || block0.DataType != DataBlk.TYPE_INT)
					block0 = new DataBlkInt();
				if (block1 == null || block1.DataType != DataBlk.TYPE_INT)
					block1 = new DataBlkInt();
				if (block2 == null || block2.DataType != DataBlk.TYPE_INT)
					block2 = new DataBlkInt();
				block0.w = block1.w = block2.w = blk.w;
				block0.h = block1.h = block2.h = blk.h;
				block0.ulx = block1.ulx = block2.ulx = blk.ulx;
				block0.uly = block1.uly = block2.uly = blk.uly;
				
				int[] data0, data1, data2; // input data arrays
				
				// Fill in buffer blocks (to be read only)
				// Returned blocks may have different size and position
				block0 = (DataBlkInt) src.getInternCompData(block0, 0);
				data0 = (int[]) block0.Data;
				block1 = (DataBlkInt) src.getInternCompData(block1, 1);
				data1 = (int[]) block1.Data;
				block2 = (DataBlkInt) src.getInternCompData(block2, 2);
				data2 = (int[]) block2.Data;
				
				// Set the progressiveness of the output data
				blk.progressive = block0.progressive || block1.progressive || block2.progressive;
				blk.offset = 0;
				blk.scanw = w;
				
				// set attributes of the DataBlk used for buffering
				dbi.progressive = blk.progressive;
				dbi.ulx = blk.ulx;
				dbi.uly = blk.uly;
				dbi.w = blk.w;
				dbi.h = blk.h;
				
				// Perform conversion
				
				// Initialize general indexes
				k = w * h - 1;
				k0 = block0.offset + (h - 1) * block0.scanw + w - 1;
				k1 = block1.offset + (h - 1) * block1.scanw + w - 1;
				k2 = block2.offset + (h - 1) * block2.scanw + w - 1;
				
				for (i = h - 1; i >= 0; i--)
				{
					for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
					{
						outdata[1][k] = (data0[k0] - ((data1[k1] + data2[k2]) >> 2));
						outdata[0][k] = data2[k2] + outdata[1][k];
						outdata[2][k] = data1[k1] + outdata[1][k];
					}
					// Jump to beggining of previous line in input
					k0 -= (block0.scanw - w);
					k1 -= (block1.scanw - w);
					k2 -= (block2.scanw - w);
				}
				outdata[c] = null;
			}
			else if ((c >= 0) && (c < 3))
			{
				//Asking for the 2nd or 3rd block component
				blk.Data = outdata[c];
				blk.progressive = dbi.progressive;
				blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx;
				blk.scanw = dbi.w;
				outdata[c] = null;
			}
			else
			{
				// Requesting a non valid component index
				throw new System.ArgumentException();
			}
			return blk;
		}
Esempio n. 36
0
 public abstract CSJ2K.j2k.image.DataBlk getInternCodeBlock(int param1, int param2, int param3, CSJ2K.j2k.wavelet.synthesis.SubbandSyn param4, CSJ2K.j2k.image.DataBlk param5);
Esempio n. 37
0
		/// <summary> Apply inverse irreversible component transformation to obtain requested
		/// component from specified block of data. Whatever the type of requested
		/// DataBlk, it always returns a DataBlkFloat.
		/// 
		/// </summary>
		/// <param name="blk">Determine the rectangular area to return 
		/// 
		/// </param>
		/// <param name="c">The index of the requested component
		/// 
		/// </param>
		/// <returns> Data of requested component
		/// 
		/// </returns>
		private DataBlk invICT(DataBlk blk, int c)
		{
			if (c >= 3 && c < NumComps)
			{
				// Requesting a component whose index is greater than 3            
                int k, k0, mink, i; //  k1, k2 removed
				int w = blk.w; //width of output block
				int h = blk.h; //height of ouput block
				
				int[] out_data; // array of output data
				
				//Reference to output block data array
				out_data = (int[]) blk.Data;
				
				//Create data array of blk if necessary
				if (out_data == null)
				{
					out_data = new int[h * w];
					blk.Data = out_data;
				}
				
				// Variables
				DataBlkFloat indb = new DataBlkFloat(blk.ulx, blk.uly, w, h);
				float[] indata; // input data array
				
				// Get the input data
				// (returned block may be larger than requested one)
				src.getInternCompData(indb, c);
				indata = (float[]) indb.Data;
				
				// Copy the data converting from int to int
				k = w * h - 1;
				k0 = indb.offset + (h - 1) * indb.scanw + w - 1;
				for (i = h - 1; i >= 0; i--)
				{
					for (mink = k - w; k > mink; k--, k0--)
					{
						//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'"
						out_data[k] = (int) (indata[k0]);
					}
					// Jump to beggining of previous line in input
					k0 -= (indb.scanw - w);
				}
				
				// Set the progressivity and offset
				blk.progressive = indb.progressive;
				blk.offset = 0;
				blk.scanw = w;
			}
			// If asking a component for the first time for this block,
			// do transform for the 3 components
			else if ((outdata[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h))
			{
				int k, k0, k1, k2, mink, i;
				int w = blk.w; //width of output block
				int h = blk.h; //height of ouput block
				
				//Reference to output block data array
				outdata[c] = (int[]) blk.Data;
				
				//Create data array of blk if necessary
				if (outdata[c] == null || outdata[c].Length != w * h)
				{
					outdata[c] = new int[h * w];
					blk.Data = outdata[c];
				}
				
				outdata[(c + 1) % 3] = new int[outdata[c].Length];
				outdata[(c + 2) % 3] = new int[outdata[c].Length];
				
				if (block0 == null || block0.DataType != DataBlk.TYPE_FLOAT)
					block0 = new DataBlkFloat();
				if (block2 == null || block2.DataType != DataBlk.TYPE_FLOAT)
					block2 = new DataBlkFloat();
				if (block1 == null || block1.DataType != DataBlk.TYPE_FLOAT)
					block1 = new DataBlkFloat();
				block0.w = block2.w = block1.w = blk.w;
				block0.h = block2.h = block1.h = blk.h;
				block0.ulx = block2.ulx = block1.ulx = blk.ulx;
				block0.uly = block2.uly = block1.uly = blk.uly;
				
				float[] data0, data1, data2; // input data arrays
				
				// Fill in buffer blocks (to be read only)
				// Returned blocks may have different size and position
				block0 = (DataBlkFloat) src.getInternCompData(block0, 0);
				data0 = (float[]) block0.Data;
				block2 = (DataBlkFloat) src.getInternCompData(block2, 1);
				data2 = (float[]) block2.Data;
				block1 = (DataBlkFloat) src.getInternCompData(block1, 2);
				data1 = (float[]) block1.Data;
				
				// Set the progressiveness of the output data
				blk.progressive = block0.progressive || block1.progressive || block2.progressive;
				blk.offset = 0;
				blk.scanw = w;
				
				// set attributes of the DataBlk used for buffering
				dbi.progressive = blk.progressive;
				dbi.ulx = blk.ulx;
				dbi.uly = blk.uly;
				dbi.w = blk.w;
				dbi.h = blk.h;
				
				//Perform conversion
				
				// Initialize general indexes
				k = w * h - 1;
				k0 = block0.offset + (h - 1) * block0.scanw + w - 1;
				k2 = block2.offset + (h - 1) * block2.scanw + w - 1;
				k1 = block1.offset + (h - 1) * block1.scanw + w - 1;
				
				for (i = h - 1; i >= 0; i--)
				{
					for (mink = k - w; k > mink; k--, k0--, k2--, k1--)
					{
						//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'"
						outdata[0][k] = (int) (data0[k0] + 1.402f * data1[k1] + 0.5f);
						//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'"
						outdata[1][k] = (int) (data0[k0] - 0.34413f * data2[k2] - 0.71414f * data1[k1] + 0.5f);
						//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'"
						outdata[2][k] = (int) (data0[k0] + 1.772f * data2[k2] + 0.5f);
					}
					// Jump to beggining of previous line in input
					k0 -= (block0.scanw - w);
					k2 -= (block2.scanw - w);
					k1 -= (block1.scanw - w);
				}
				outdata[c] = null;
			}
			else if ((c >= 0) && (c <= 3))
			{
				//Asking for the 2nd or 3rd block component
				blk.Data = outdata[c];
				blk.progressive = dbi.progressive;
				blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx;
				blk.scanw = dbi.w;
				outdata[c] = null;
			}
			else
			{
				// Requesting a non valid component index
				throw new System.ArgumentException();
			}
			return blk;
		}