예제 #1
0
 /// <summary> Copy constructor. Creates a DataBlkFloat which is the copy of the
 /// DataBlkFloat given as paramter.
 ///
 /// </summary>
 /// <param name="DataBlkFloat">the object to be copied.
 ///
 /// </param>
 public DataBlkFloat(DataBlkFloat src)
 {
     this.ulx    = src.ulx;
     this.uly    = src.uly;
     this.w      = src.w;
     this.h      = src.h;
     this.offset = 0;
     this.scanw  = this.w;
     this.data   = new float[this.w * this.h];
     for (int i = 0; i < this.h; i++)
     {
         Array.Copy(src.data, i * src.scanw, this.data, i * this.scanw, this.w);
     }
 }
예제 #2
0
		/// <summary> Copy constructor. Creates a DataBlkFloat which is the copy of the
		/// DataBlkFloat given as paramter.
		/// 
		/// </summary>
		/// <param name="DataBlkFloat">the object to be copied.
		/// 
		/// </param>
		public DataBlkFloat(DataBlkFloat src)
		{
			this.ulx = src.ulx;
			this.uly = src.uly;
			this.w = src.w;
			this.h = src.h;
			this.offset = 0;
			this.scanw = this.w;
			this.data = new float[this.w * this.h];
			for (int i = 0; i < this.h; i++)
				Array.Copy(src.data, i * src.scanw, this.data, i * this.scanw, this.w);
		}
예제 #3
0
파일: InvWTFull.cs 프로젝트: cureos/csj2k
        /// <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);
                }
            }
        }
예제 #4
0
파일: InvWTFull.cs 프로젝트: cureos/csj2k
        /// <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;
        }
예제 #5
0
		/// <summary> Returns the next code-block in the current tile for the specified
		/// component. The order in which code-blocks are returned is not
		/// specified. However each code-block is returned only once and all
		/// code-blocks will be returned if the method is called 'N' times, where
		/// 'N' is the number of code-blocks in the tile. After all the code-blocks
		/// have been returned for the current tile calls to this method will
		/// return 'null'.
		/// 
		/// <p>When changing the current tile (through 'setTile()' or 'nextTile()')
		/// this method will always return the first code-block, as if this method
		/// was never called before for the new current tile.</p>
		/// 
		/// <p>The data returned by this method is the data in the internal buffer
		/// of this object, and thus can not be modified by the caller. The
		/// 'offset' and 'scanw' of the returned data have, in general, some
		/// non-zero value. The 'magbits' of the returned data is not set by this
		/// method and should be ignored. See the 'CBlkWTData' class.</p>
		/// 
		/// <p>The 'ulx' and 'uly' members of the returned 'CBlkWTData' 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="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.
		/// 
		/// </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="CBlkWTData">
		/// 
		/// </seealso>
		public override CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk)
		{
			int cbm, cbn, cn, cm;
			int acb0x, acb0y;
			SubbandAn sb;
			intData = (filters.getWTDataType(tIdx, c) == DataBlk.TYPE_INT);
			
			//If the source image has not been decomposed 
			if (decomposedComps[c] == null)
			{
				int k, w, h;
				DataBlk bufblk;
				System.Object dst_data;
				
				w = getTileCompWidth(tIdx, c);
				h = getTileCompHeight(tIdx, c);
				
				//Get the source image data
				if (intData)
				{
					decomposedComps[c] = new DataBlkInt(0, 0, w, h);
					bufblk = new DataBlkInt();
				}
				else
				{
					decomposedComps[c] = new DataBlkFloat(0, 0, w, h);
					bufblk = new DataBlkFloat();
				}
				
				// Get data from source line by line (this diminishes the memory
				// requirements on the data source)
				dst_data = decomposedComps[c].Data;
				int lstart = getCompULX(c);
				bufblk.ulx = lstart;
				bufblk.w = w;
				bufblk.h = 1;
				int kk = getCompULY(c);
				for (k = 0; k < h; k++, kk++)
				{
					bufblk.uly = kk;
					bufblk.ulx = lstart;
					bufblk = src.getInternCompData(bufblk, c);
                    // CONVERSION PROBLEM?
					Array.Copy((System.Array)bufblk.Data, bufblk.offset, (System.Array)dst_data, k * w, w);
				}
				
				//Decompose source image
				waveletTreeDecomposition(decomposedComps[c], getAnSubbandTree(tIdx, c), c);
				
				// Make the first subband the current one
				currentSubband[c] = getNextSubband(c);
				
				lastn[c] = - 1;
				lastm[c] = 0;
			}
			
			// Get the next code-block to "send"
			do 
			{
				// Calculate number of code-blocks in current subband
				ncblks = currentSubband[c].numCb;
				// Goto next code-block
				lastn[c]++;
				if (lastn[c] == ncblks.x)
				{
					// Got to end of this row of
					// code-blocks
					lastn[c] = 0;
					lastm[c]++;
				}
				if (lastm[c] < ncblks.y)
				{
					// Not past the last code-block in the subband, we can return
					// this code-block
					break;
				}
				// If we get here we already sent all code-blocks in this subband,
				// goto next subband
				currentSubband[c] = getNextSubband(c);
				lastn[c] = - 1;
				lastm[c] = 0;
				if (currentSubband[c] == null)
				{
					// We don't need the transformed data any more (a priori)
					decomposedComps[c] = null;
					// All code-blocks from all subbands in the current
					// tile have been returned so we return a null
					// reference
					return null;
				}
				// Loop to find the next code-block
			}
			while (true);
			
			
			// Project code-block partition origin to subband. Since the origin is
			// always 0 or 1, it projects to the low-pass side (throught the ceil
			// operator) as itself (i.e. no change) and to the high-pass side
			// (through the floor operator) as 0, always.
			acb0x = cb0x;
			acb0y = cb0y;
			switch (currentSubband[c].sbandIdx)
			{
				
				case Subband.WT_ORIENT_LL: 
					// No need to project since all low-pass => nothing to do
					break;
				
				case Subband.WT_ORIENT_HL: 
					acb0x = 0;
					break;
				
				case Subband.WT_ORIENT_LH: 
					acb0y = 0;
					break;
				
				case Subband.WT_ORIENT_HH: 
					acb0x = 0;
					acb0y = 0;
					break;
				
				default: 
					throw new System.ApplicationException("Internal JJ2000 error");
				
			}
			
			// Initialize output code-block
			if (cblk == null)
			{
				if (intData)
				{
					cblk = new CBlkWTDataInt();
				}
				else
				{
					cblk = new CBlkWTDataFloat();
				}
			}
			cbn = lastn[c];
			cbm = lastm[c];
			sb = currentSubband[c];
			cblk.n = cbn;
			cblk.m = cbm;
			cblk.sb = sb;
			// Calculate the indexes of first code-block in subband with respect
			// to the partitioning origin, to then calculate the position and size
			// NOTE: when calculating "floor()" by integer division the dividend
			// and divisor must be positive, we ensure that by adding the divisor
			// to the dividend and then substracting 1 to the result of the
			// division
			cn = (sb.ulcx - acb0x + sb.nomCBlkW) / sb.nomCBlkW - 1;
			cm = (sb.ulcy - acb0y + sb.nomCBlkH) / sb.nomCBlkH - 1;
			if (cbn == 0)
			{
				// Left-most code-block, starts where subband starts
				cblk.ulx = sb.ulx;
			}
			else
			{
				// Calculate starting canvas coordinate and convert to subb. coords
				cblk.ulx = (cn + cbn) * sb.nomCBlkW - (sb.ulcx - acb0x) + sb.ulx;
			}
			if (cbm == 0)
			{
				// Bottom-most code-block, starts where subband starts
				cblk.uly = sb.uly;
			}
			else
			{
				cblk.uly = (cm + cbm) * sb.nomCBlkH - (sb.ulcy - acb0y) + sb.uly;
			}
			if (cbn < ncblks.x - 1)
			{
				// Calculate where next code-block starts => width
				cblk.w = (cn + cbn + 1) * sb.nomCBlkW - (sb.ulcx - acb0x) + sb.ulx - cblk.ulx;
			}
			else
			{
				// Right-most code-block, ends where subband ends
				cblk.w = sb.ulx + sb.w - cblk.ulx;
			}
			if (cbm < ncblks.y - 1)
			{
				// Calculate where next code-block starts => height
				cblk.h = (cm + cbm + 1) * sb.nomCBlkH - (sb.ulcy - acb0y) + sb.uly - cblk.uly;
			}
			else
			{
				// Bottom-most code-block, ends where subband ends
				cblk.h = sb.uly + sb.h - cblk.uly;
			}
			cblk.wmseScaling = 1f;
			
			// Since we are in getNextInternCodeBlock() we can return a
			// reference to the internal buffer, no need to copy. Just initialize
			// the 'offset' and 'scanw'
			cblk.offset = cblk.uly * decomposedComps[c].w + cblk.ulx;
			cblk.scanw = decomposedComps[c].w;
			
			// For the data just put a reference to our buffer
			cblk.Data = decomposedComps[c].Data;
			// Return code-block
			return cblk;
		}
예제 #6
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;
		}
예제 #7
0
		/// <summary> Return a DataBlk containing the requested component
		/// upsampled by the scale factor applied to the particular
		/// scaling direction
		/// 
		/// 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>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 set to that of the
		/// input data.
		/// 
		/// </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
		/// and 3 are valid.
		/// 
		/// </param>
		/// <returns> The requested DataBlk
		/// 
		/// </returns>
		/// <seealso cref="getCompData">
		/// </seealso>
		public override DataBlk getInternCompData(DataBlk outblk, int c)
		{
			
			// If the scaling factor of this channel is 1 in both
			// directions, simply return the source DataBlk.
			
			if (src.getCompSubsX(c) == 1 && src.getCompSubsY(c) == 1)
				return src.getInternCompData(outblk, c);
			
			int wfactor = src.getCompSubsX(c);
			int hfactor = src.getCompSubsY(c);
			if ((wfactor != 2 && wfactor != 1) || (hfactor != 2 && hfactor != 1))
				throw new System.ArgumentException("Upsampling by other than 2:1" + " not supported");
			
			int leftedgeOut = - 1; // offset to the start of the output scanline
			int rightedgeOut = - 1; // offset to the end of the output
			// scanline + 1
			int leftedgeIn = - 1; // offset to the start of the input scanline  
			int rightedgeIn = - 1; // offset to the end of the input scanline + 1
			
			
			int y0In, y1In, y0Out, y1Out;
			int x0In, x1In, x0Out, x1Out;
			
			y0Out = outblk.uly;
			y1Out = y0Out + outblk.h - 1;
			
			x0Out = outblk.ulx;
			x1Out = x0Out + outblk.w - 1;
			
			y0In = y0Out / hfactor;
			y1In = y1Out / hfactor;
			
			x0In = x0Out / wfactor;
			x1In = x1Out / wfactor;
			
			
			// Calculate the requested height and width, requesting an extra
			// row and or for upsampled channels.
			int reqW = x1In - x0In + 1;
			int reqH = y1In - y0In + 1;
			
			// Initialize general input and output indexes
			int kOut = - 1;
			int kIn = - 1;
			int yIn;
			
			switch (outblk.DataType)
			{
				
				
				case DataBlk.TYPE_INT: 
					
					DataBlkInt inblkInt = new DataBlkInt(x0In, y0In, reqW, reqH);
					inblkInt = (DataBlkInt) src.getInternCompData(inblkInt, c);
					dataInt[c] = inblkInt.DataInt;
					
					// Reference the working array   
					int[] outdataInt = (int[]) outblk.Data;
					
					// Create data array if necessary
					if (outdataInt == null || outdataInt.Length != outblk.w * outblk.h)
					{
						outdataInt = new int[outblk.h * outblk.w];
						outblk.Data = outdataInt;
					}
					
					// The nitty-gritty.
					
					for (int yOut = y0Out; yOut <= y1Out; ++yOut)
					{
						
						yIn = yOut / hfactor;
						
						
						leftedgeIn = inblkInt.offset + (yIn - y0In) * inblkInt.scanw;
						rightedgeIn = leftedgeIn + inblkInt.w;
						leftedgeOut = outblk.offset + (yOut - y0Out) * outblk.scanw;
						rightedgeOut = leftedgeOut + outblk.w;
						
						kIn = leftedgeIn;
						kOut = leftedgeOut;
						
						if ((x0Out & 0x1) == 1)
						{
							// first is odd do the pixel once.
							outdataInt[kOut++] = dataInt[c][kIn++];
						}
						
						if ((x1Out & 0x1) == 0)
						{
							// last is even adjust loop bounds
							rightedgeOut--;
						}
						
						while (kOut < rightedgeOut)
						{
							outdataInt[kOut++] = dataInt[c][kIn];
							outdataInt[kOut++] = dataInt[c][kIn++];
						}
						
						if ((x1Out & 0x1) == 0)
						{
							// last is even do the pixel once.
							outdataInt[kOut++] = dataInt[c][kIn];
						}
					}
					
					outblk.progressive = inblkInt.progressive;
					break;
				
				
				case DataBlk.TYPE_FLOAT: 
					
					DataBlkFloat inblkFloat = new DataBlkFloat(x0In, y0In, reqW, reqH);
					inblkFloat = (DataBlkFloat) src.getInternCompData(inblkFloat, c);
					dataFloat[c] = inblkFloat.DataFloat;
					
					// Reference the working array   
					float[] outdataFloat = (float[]) outblk.Data;
					
					// Create data array if necessary
					if (outdataFloat == null || outdataFloat.Length != outblk.w * outblk.h)
					{
						outdataFloat = new float[outblk.h * outblk.w];
						outblk.Data = outdataFloat;
					}
					
					// The nitty-gritty.
					
					for (int yOut = y0Out; yOut <= y1Out; ++yOut)
					{
						
						yIn = yOut / hfactor;
						
						
						leftedgeIn = inblkFloat.offset + (yIn - y0In) * inblkFloat.scanw;
						rightedgeIn = leftedgeIn + inblkFloat.w;
						leftedgeOut = outblk.offset + (yOut - y0Out) * outblk.scanw;
						rightedgeOut = leftedgeOut + outblk.w;
						
						kIn = leftedgeIn;
						kOut = leftedgeOut;
						
						if ((x0Out & 0x1) == 1)
						{
							// first is odd do the pixel once.
							outdataFloat[kOut++] = dataFloat[c][kIn++];
						}
						
						if ((x1Out & 0x1) == 0)
						{
							// last is even adjust loop bounds
							rightedgeOut--;
						}
						
						while (kOut < rightedgeOut)
						{
							outdataFloat[kOut++] = dataFloat[c][kIn];
							outdataFloat[kOut++] = dataFloat[c][kIn++];
						}
						
						if ((x1Out & 0x1) == 0)
						{
							// last is even do the pixel once.
							outdataFloat[kOut++] = dataFloat[c][kIn];
						}
					}
					
					outblk.progressive = inblkFloat.progressive;
					break;
				
				
				case DataBlk.TYPE_SHORT: 
				case DataBlk.TYPE_BYTE: 
				default: 
					// Unsupported output type. 
					throw new System.ArgumentException("invalid source datablock " + "type");
				}
			
			return outblk;
		}
예제 #8
0
        /// <summary>General utility used by ctors </summary>
        private void initialize()
        {
            this.pl = csMap.pl;
            this.ncomps = src.NumComps;

            shiftValueArray = new int[ncomps];
            maxValueArray = new int[ncomps];
            fixedPtBitsArray = new int[ncomps];

            srcBlk = new DataBlk[ncomps];
            inInt = new DataBlkInt[ncomps];
            inFloat = new DataBlkFloat[ncomps];
            workInt = new DataBlkInt[ncomps];
            workFloat = new DataBlkFloat[ncomps];
            dataInt = new int[ncomps][];
            dataFloat = new float[ncomps][];
            workDataInt = new int[ncomps][];
            workDataFloat = new float[ncomps][];
            dataInt = new int[ncomps][];
            dataFloat = new float[ncomps][];

            /* For each component, get a reference to the pixel data and
            * set up working DataBlks for both integer and float output.
            */
            for (int i = 0; i < ncomps; ++i)
            {

                shiftValueArray[i] = 1 << (src.getNomRangeBits(i) - 1);
                maxValueArray[i] = (1 << src.getNomRangeBits(i)) - 1;
                fixedPtBitsArray[i] = src.getFixedPoint(i);

                inInt[i] = new DataBlkInt();
                inFloat[i] = new DataBlkFloat();
                workInt[i] = new DataBlkInt();
                workInt[i].progressive = inInt[i].progressive;
                workFloat[i] = new DataBlkFloat();
                workFloat[i].progressive = inFloat[i].progressive;
            }
        }
예제 #9
0
		/// <summary>General utility used by ctors </summary>
		private void  initialize()
		{
			
			tempInt = new DataBlkInt[ncomps];
			tempFloat = new DataBlkFloat[ncomps];
			
			/* For each component, get the maximum data value, a reference
			* to the pixel data and set up working and temporary DataBlks
			* for both integer and float output.
			*/
			for (int i = 0; i < ncomps; ++i)
			{
				tempInt[i] = new DataBlkInt();
				tempFloat[i] = new DataBlkFloat();
			}
		}
예제 #10
0
		/// <summary> Returns the specified code-block in the current tile for the specified
		/// component (as a reference or copy).
		/// 
		/// <p>The returned code-block may be progressive, which is indicated by
		/// the 'progressive' variable of the returned 'DataBlk'
		/// object. If a code-block is progressive it means that in a later request
		/// to this method for the same code-block it is possible to retrieve data
		/// which is a better approximation, since meanwhile more data to decode
		/// for the code-block could have been received. If the code-block is not
		/// progressive then later calls to this method for the same code-block
		/// will return the exact same data values.</p>
		/// 
		/// <p>The data returned by this method can be the data in the internal
		/// buffer of this object, if any, and thus can not be modified by the
		/// caller. The 'offset' and 'scanw' of the returned data can be
		/// arbitrary. See the 'DataBlk' class.</p>
		/// 
		/// </summary>
		/// <param name="c">The component for which to return the next code-block.
		/// 
		/// </param>
		/// <param name="m">The vertical index of the code-block to return, in the
		/// specified subband.
		/// 
		/// </param>
		/// <param name="n">The horizontal index of the code-block to return, in the
		/// specified subband.
		/// 
		/// </param>
		/// <param name="sb">The subband in which the code-block to return is.
		/// 
		/// </param>
		/// <param name="cblk">If non-null this object will be used to return the new
		/// code-block. If null a new one will be allocated and returned. If the
		/// "data" array of the object is non-null it will be reused, if possible,
		/// to return the data.
		/// 
		/// </param>
		/// <returns> The next code-block in the current tile for component 'n', or
		/// null if all code-blocks for the current tile have been returned.
		/// 
		/// </returns>
		/// <seealso cref="DataBlk">
		/// 
		/// </seealso>
		public override DataBlk getInternCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
		{
			// This method is declared final since getNextCodeBlock() relies on
			// the actual implementation of this method.
			int j, jmin, k;
			int temp;
			float step;
			int shiftBits;
			int magBits;
			int[] outiarr, inarr;
			float[] outfarr;
			int w, h;
			bool reversible = qts.isReversible(tIdx, c);
			bool derived = qts.isDerived(tIdx, c);
			StdDequantizerParams params_Renamed = (StdDequantizerParams) qsss.getTileCompVal(tIdx, c);
			int G = ((System.Int32) gbs.getTileCompVal(tIdx, c));
			
			outdtype = cblk.DataType;
			
			if (reversible && outdtype != DataBlk.TYPE_INT)
			{
				throw new System.ArgumentException("Reversible quantizations " + "must use int data");
			}
			
			// To get compiler happy
			outiarr = null;
			outfarr = null;
			inarr = null;
			
			// Get source data and initialize output DataBlk object.
			switch (outdtype)
			{
				
				case DataBlk.TYPE_INT: 
					// With int data we can use the same DataBlk object to get the
					// data from the source and return the dequantized data, and we
					// can also work "in place" (i.e. same buffer).
					cblk = src.getCodeBlock(c, m, n, sb, cblk);
					// Input and output arrays are the same
					outiarr = (int[]) cblk.Data;
					break;
				
				case DataBlk.TYPE_FLOAT: 
					// With float data we must use a different DataBlk objects to get
					// the data from the source and to return the dequantized data.
					inblk = (DataBlkInt) src.getInternCodeBlock(c, m, n, sb, inblk);
					inarr = inblk.DataInt;
					if (cblk == null)
					{
						cblk = new DataBlkFloat();
					}
					// Copy the attributes of the CodeBlock object
					cblk.ulx = inblk.ulx;
					cblk.uly = inblk.uly;
					cblk.w = inblk.w;
					cblk.h = inblk.h;
					cblk.offset = 0;
					cblk.scanw = cblk.w;
					cblk.progressive = inblk.progressive;
					// Get output data array and check its size
					outfarr = (float[]) cblk.Data;
					if (outfarr == null || outfarr.Length < cblk.w * cblk.h)
					{
						outfarr = new float[cblk.w * cblk.h];
						cblk.Data = outfarr;
					}
					break;
				}
			
			magBits = sb.magbits;
			
			// Calculate quantization step and number of magnitude bits
			// depending on reversibility and derivedness and perform
			// inverse quantization
			if (reversible)
			{
				shiftBits = 31 - magBits;
				// For int data Inverse quantization happens "in-place". The input
				// array has an offset of 0 and scan width equal to the code-block
				// width.
				for (j = outiarr.Length - 1; j >= 0; j--)
				{
					temp = outiarr[j]; // input array is same as output one
					outiarr[j] = (temp >= 0)?(temp >> shiftBits):- ((temp & 0x7FFFFFFF) >> shiftBits);
				}
			}
			else
			{
				// Not reversible 
				if (derived)
				{
					// Max resolution level
					int mrl = src.getSynSubbandTree(TileIdx, c).resLvl;
					step = params_Renamed.nStep[0][0] * (1L << (rb[c] + sb.anGainExp + mrl - sb.level));
				}
				else
				{
					step = params_Renamed.nStep[sb.resLvl][sb.sbandIdx] * (1L << (rb[c] + sb.anGainExp));
				}
				shiftBits = 31 - magBits;
				
				// Adjust step to the number of shiftBits
				step /= (1 << shiftBits);
				
				switch (outdtype)
				{
					
					case DataBlk.TYPE_INT: 
						// For int data Inverse quantization happens "in-place". The
						// input array has an offset of 0 and scan width equal to the
						// code-block width.
						for (j = outiarr.Length - 1; j >= 0; j--)
						{
							temp = outiarr[j]; // input array is same as output one
							//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
							outiarr[j] = (int) (((float) ((temp >= 0)?temp:- (temp & 0x7FFFFFFF))) * step);
						}
						break;
					
					case DataBlk.TYPE_FLOAT: 
						// For float data the inverse quantization can not happen
						// "in-place".
						w = cblk.w;
						h = cblk.h;
						for (j = w * h - 1, k = inblk.offset + (h - 1) * inblk.scanw + w - 1, jmin = w * (h - 1); j >= 0; jmin -= w)
						{
							for (; j >= jmin; k--, j--)
							{
								temp = inarr[k];
								//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
								outfarr[j] = ((float) ((temp >= 0)?temp:- (temp & 0x7FFFFFFF))) * step;
							}
							// Jump to beggining of previous line in input
							k -= (inblk.scanw - w);
						}
						break;
					}
			}
			// Return the output code-block
			return cblk;
		}