Example #1
0
		/// <summary> Compresses the code-block in 'srcblk' and puts the results in 'ccb',
		/// using the specified options and temporary storage.
		/// 
		/// </summary>
		/// <param name="c">The component for which to return the next code-block.
		/// 
		/// </param>
		/// <param name="ccb">The object where the compressed data will be stored. If the
		/// 'data' array of 'cbb' is not null it may be reused to return the
		/// compressed data.
		/// 
		/// </param>
		/// <param name="srcblk">The code-block data to code
		/// 
		/// </param>
		/// <param name="mq">The MQ-coder to use
		/// 
		/// </param>
		/// <param name="bout">The bit level output to use. Used only if 'OPT_BYPASS' is
		/// turned on in the 'options' argument.
		/// 
		/// </param>
		/// <param name="out">The byte buffer trough which the compressed data is stored.
		/// 
		/// </param>
		/// <param name="state">The state information for the code-block
		/// 
		/// </param>
		/// <param name="distbuf">The buffer where to store the distortion  at 
		/// the end of each coding pass.
		/// 
		/// </param>
		/// <param name="ratebuf">The buffer where to store the rate (i.e. coded lenth) at 
		/// the end of each coding pass.
		/// 
		/// </param>
		/// <param name="istermbuf">The buffer where to store the terminated flag for each 
		/// coding pass.
		/// 
		/// </param>
		/// <param name="symbuf">The buffer to hold symbols to send to the MQ coder
		/// 
		/// </param>
		/// <param name="ctxtbuf">A buffer to hold the contexts to use in sending the
		/// buffered symbols to the MQ coder.
		/// 
		/// </param>
		/// <param name="options">The options to use when coding this code-block
		/// 
		/// </param>
		/// <param name="rev">The reversible flag. Should be true if the source of this
		/// code-block's data is reversible.
		/// 
		/// </param>
		/// <param name="lcType">The type of length calculation to use with the MQ coder.
		/// 
		/// </param>
		/// <param name="tType">The type of termination to use with the MQ coder.
		/// 
		/// </param>
		/// <seealso cref="getNextCodeBlock">
		/// 
		/// </seealso>
		static private void  compressCodeBlock(int c, CBlkRateDistStats ccb, CBlkWTData srcblk, MQCoder mq, BitToByteOutput bout, ByteOutputBuffer out_Renamed, int[] state, double[] distbuf, int[] ratebuf, bool[] istermbuf, int[] symbuf, int[] ctxtbuf, int options, bool rev, int lcType, int tType)
		{
			// NOTE: This method should not access any non-final instance or
			// static variables, either directly or indirectly through other
			// methods in order to be sure that the method is thread safe.
			
			int[] zc_lut; // The ZC lookup table to use
			int skipbp; // The number of non-significant bit-planes to skip
			int curbp; // The current magnitude bit-plane (starts at 30)
			int[] fm; // The distortion estimation lookup table for MR
			int[] fs; // The distortion estimation lookup table for SC
			int lmb; // The least significant magnitude bit
			int npass; // The number of coding passes, for R-D statistics
			double msew; // The distortion (MSE weight) for the current bit-plane
			double totdist; // The total cumulative distortion decrease
			int ltpidx; // The index of the last pass which is terminated
			
			// Check error-resilient termination
			if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0 && tType != MQCoder.TERM_PRED_ER)
			{
				throw new System.ArgumentException("Embedded error-resilient info " + "in MQ termination option " + "specified but incorrect MQ " + "termination " + "policy specified");
			}
			// Set MQ flags
			mq.LenCalcType = lcType;
			mq.TermType = tType;
			
			lmb = 30 - srcblk.magbits + 1;
			// If there are more bit-planes to code than the implementation
			// bit-depth set lmb to 0
			lmb = (lmb < 0)?0:lmb;
			
			// Reset state
			ArrayUtil.intArraySet(state, 0);
			
			// Find the most significant bit-plane
			skipbp = calcSkipMSBP(srcblk, lmb);
			
			// Initialize output code-block
			ccb.m = srcblk.m;
			ccb.n = srcblk.n;
			ccb.sb = srcblk.sb;
			ccb.nROIcoeff = srcblk.nROIcoeff;
			ccb.skipMSBP = skipbp;
			if (ccb.nROIcoeff != 0)
			{
				ccb.nROIcp = 3 * (srcblk.nROIbp - skipbp - 1) + 1;
			}
			else
			{
				ccb.nROIcp = 0;
			}
			
			// Choose correct ZC lookup table for global orientation
			switch (srcblk.sb.orientation)
			{
				
				case Subband.WT_ORIENT_HL: 
					zc_lut = ZC_LUT_HL;
					break;
				
				case Subband.WT_ORIENT_LL: 
				case Subband.WT_ORIENT_LH: 
					zc_lut = ZC_LUT_LH;
					break;
				
				case Subband.WT_ORIENT_HH: 
					zc_lut = ZC_LUT_HH;
					break;
				
				default: 
					throw new System.InvalidOperationException("JJ2000 internal error");
				
			}
			
			// Loop on significant magnitude bit-planes doing the 3 passes
			curbp = 30 - skipbp;
			fs = FS_LOSSY;
			fm = FM_LOSSY;
			msew = System.Math.Pow(2, ((curbp - lmb) << 1) - MSE_LKP_FRAC_BITS) * srcblk.sb.stepWMSE * srcblk.wmseScaling;
			totdist = 0f;
			npass = 0;
			ltpidx = - 1;
			
			// First significant bit-plane has only the pass pass
			if (curbp >= lmb)
			{
				// Do we need the "lossless" 'fs' table ?
				if (rev && curbp == lmb)
				{
					fs = FM_LOSSLESS;
				}
				// We terminate if regular termination, last bit-plane, or next
				// bit-plane is "raw".
				istermbuf[npass] = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || curbp == lmb || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp) >= curbp);
				totdist += cleanuppass(srcblk, mq, istermbuf[npass], curbp, state, fs, zc_lut, symbuf, ctxtbuf, ratebuf, npass, ltpidx, options) * msew;
				distbuf[npass] = totdist;
				if (istermbuf[npass])
					ltpidx = npass;
				npass++;
				msew *= 0.25;
				curbp--;
			}
			// Other bit-planes have all passes
			while (curbp >= lmb)
			{
				// Do we need the "lossless" 'fs' and 'fm' tables ?
				if (rev && curbp == lmb)
				{
					fs = FS_LOSSLESS;
					fm = FM_LOSSLESS;
				}
				
				// Do the significance propagation pass
				// We terminate if regular termination only
				istermbuf[npass] = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0;
				if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) == 0 || (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp <= curbp))
				{
					// No bypass coding
					totdist += sigProgPass(srcblk, mq, istermbuf[npass], curbp, state, fs, zc_lut, symbuf, ctxtbuf, ratebuf, npass, ltpidx, options) * msew;
				}
				else
				{
					// Bypass ("raw") coding
					bout.PredTerm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0;
					totdist += rawSigProgPass(srcblk, bout, istermbuf[npass], curbp, state, fs, ratebuf, npass, ltpidx, options) * msew;
				}
				distbuf[npass] = totdist;
				if (istermbuf[npass])
					ltpidx = npass;
				npass++;
				
				// Do the magnitude refinement pass
				// We terminate if regular termination or bypass ("raw") coding
				istermbuf[npass] = (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 - skipbp > curbp));
				if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) == 0 || (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp <= curbp))
				{
					// No bypass coding
					totdist += magRefPass(srcblk, mq, istermbuf[npass], curbp, state, fm, symbuf, ctxtbuf, ratebuf, npass, ltpidx, options) * msew;
				}
				else
				{
					// Bypass ("raw") coding
					bout.PredTerm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0;
					totdist += rawMagRefPass(srcblk, bout, istermbuf[npass], curbp, state, fm, ratebuf, npass, ltpidx, options) * msew;
				}
				distbuf[npass] = totdist;
				if (istermbuf[npass])
					ltpidx = npass;
				npass++;
				
				// Do the clenup pass
				// We terminate if regular termination, last bit-plane, or next
				// bit-plane is "raw".
				istermbuf[npass] = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || curbp == lmb || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp) >= curbp);
				totdist += cleanuppass(srcblk, mq, istermbuf[npass], curbp, state, fs, zc_lut, symbuf, ctxtbuf, ratebuf, npass, ltpidx, options) * msew;
				distbuf[npass] = totdist;
				
				if (istermbuf[npass])
					ltpidx = npass;
				npass++;
				
				// Goto next bit-plane
				msew *= 0.25;
				curbp--;
			}
			
			// Copy compressed data and rate-distortion statistics to output
			ccb.data = new byte[out_Renamed.size()];
			out_Renamed.toByteArray(0, out_Renamed.size(), ccb.data, 0);
			checkEndOfPassFF(ccb.data, ratebuf, istermbuf, npass);
			ccb.selectConvexHull(ratebuf, distbuf, (options & (CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS)) != 0?istermbuf:null, npass, rev);
			
			// Reset MQ coder and bit output for next code-block
			mq.reset();
			if (bout != null)
				bout.reset();
		}
Example #2
0
		/// <summary> Instantiates a new entropy coder engine, with the specified source of
		/// data, nominal block width and height.
		/// 
		/// <p>If the 'OPT_PRED_TERM' option is given then the MQ termination must
		/// be 'TERM_PRED_ER' or an exception is thrown.</p>
		/// 
		/// </summary>
		/// <param name="src">The source of data
		/// 
		/// </param>
		/// <param name="cbks">Code-block size specifications
		/// 
		/// </param>
		/// <param name="pss">Precinct partition specifications
		/// 
		/// </param>
		/// <param name="bms">By-pass mode specifications
		/// 
		/// </param>
		/// <param name="mqrs">MQ-reset specifications
		/// 
		/// </param>
		/// <param name="rts">Regular termination specifications
		/// 
		/// </param>
		/// <param name="css">Causal stripes specifications
		/// 
		/// </param>
		/// <param name="sss">Error resolution segment symbol use specifications
		/// 
		/// </param>
		/// <param name="lcs">Length computation specifications
		/// 
		/// </param>
		/// <param name="tts">Termination type specifications
		/// 
		/// </param>
		/// <seealso cref="MQCoder">
		/// 
		/// </seealso>
		public StdEntropyCoder(CBlkQuantDataSrcEnc src, CBlkSizeSpec cblks, PrecinctSizeSpec pss, StringSpec bms, StringSpec mqrs, StringSpec rts, StringSpec css, StringSpec sss, StringSpec lcs, StringSpec tts):base(src)
		{
			this.cblks = cblks;
			this.pss = pss;
			this.bms = bms;
			this.mqrs = mqrs;
			this.rts = rts;
			this.css = css;
			this.sss = sss;
			this.lcs = lcs;
			this.tts = tts;
			int maxCBlkWidth, maxCBlkHeight;
			int i; // Counter
			int tsl; // Size for thread structures
			
			// Get the biggest width/height for the code-blocks
			maxCBlkWidth = cblks.MaxCBlkWidth;
			maxCBlkHeight = cblks.MaxCBlkHeight;
			
			// If we do timing create necessary structures
#if DO_TIMING
			time = new long[src.NumComps];
			// If we are timing make sure that 'finalize' gets called.
			//UPGRADE_ISSUE: Method 'java.lang.System.runFinalizersOnExit' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'"
			// CONVERSION PROBLEM?
            //System_Renamed.runFinalizersOnExit(true);
#endif
		
			tsl = 1;
			finishedTileComponent = null;
			
			// Allocate data structures
			outT = new ByteOutputBuffer[tsl];
			mqT = new MQCoder[tsl];
			boutT = new BitToByteOutput[tsl];
			stateT = new int[tsl][];
			for (int i2 = 0; i2 < tsl; i2++)
			{
				stateT[i2] = new int[(maxCBlkWidth + 2) * ((maxCBlkHeight + 1) / 2 + 2)];
			}
			symbufT = new int[tsl][];
			for (int i3 = 0; i3 < tsl; i3++)
			{
				symbufT[i3] = new int[maxCBlkWidth * (CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT * 2 + 2)];
			}
			ctxtbufT = new int[tsl][];
			for (int i4 = 0; i4 < tsl; i4++)
			{
				ctxtbufT[i4] = new int[maxCBlkWidth * (CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT * 2 + 2)];
			}
			distbufT = new double[tsl][];
			for (int i5 = 0; i5 < tsl; i5++)
			{
				distbufT[i5] = new double[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
			}
			ratebufT = new int[tsl][];
			for (int i6 = 0; i6 < tsl; i6++)
			{
				ratebufT[i6] = new int[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
			}
			istermbufT = new bool[tsl][];
			for (int i7 = 0; i7 < tsl; i7++)
			{
				istermbufT[i7] = new bool[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
			}
			srcblkT = new CBlkWTData[tsl];
			for (i = 0; i < tsl; i++)
			{
				outT[i] = new ByteOutputBuffer();
				mqT[i] = new MQCoder(outT[i], NUM_CTXTS, MQ_INIT);
			}
			precinctPartition = new bool[src.NumComps][];
			for (int i8 = 0; i8 < src.NumComps; i8++)
			{
				precinctPartition[i8] = new bool[src.getNumTiles()];
			}
			
			// Create the subband description for each component and each tile
			//Subband sb = null;
			Coord numTiles = null;
			int nc = NumComps;
			numTiles = src.getNumTiles(numTiles);
			initTileComp(getNumTiles(), nc);
			
			for (int c = 0; c < nc; c++)
			{
				for (int tY = 0; tY < numTiles.y; tY++)
				{
					for (int tX = 0; tX < numTiles.x; tX++)
					{
						precinctPartition[c][tIdx] = false;
					}
				}
			}
		}
Example #3
0
		/// <summary> Instantiates a new MQ-coder, with the specified number of contexts and
		/// initial states. The compressed bytestream is written to the 'oStream'
		/// object.
		/// 
		/// </summary>
		/// <param name="oStream">where to output the compressed data.
		/// 
		/// </param>
		/// <param name="nrOfContexts">The number of contexts used by the MQ coder.
		/// 
		/// </param>
		/// <param name="init">The initial state for each context. A reference is kept to
		/// this array to reinitialize the contexts whenever 'reset()' or
		/// 'resetCtxts()' is called.
		/// 
		/// </param>
		public MQCoder(ByteOutputBuffer oStream, int nrOfContexts, int[] init)
		{
			out_Renamed = oStream;
			
			// --- INITENC
			
			// Default initialization of the statistics bins is MPS=0 and
			// I=0
			I = new int[nrOfContexts];
			mPS = new int[nrOfContexts];
			initStates = init;
			
			a = 0x8000;
			c = 0;
			if (b == 0xFF)
			{
				cT = 13;
			}
			else
			{
				cT = 12;
			}
			
			resetCtxts();
			
			// End of INITENC ---
			b = 0;
		}
Example #4
0
		/// <summary> Instantiates a new 'BitToByteOutput' object that uses 'out' as the
		/// underlying byte based output.
		/// 
		/// </summary>
		/// <param name="out">The underlying byte based output
		/// 
		/// </param>
		internal BitToByteOutput(ByteOutputBuffer out_Renamed)
		{
			this.out_Renamed = out_Renamed;
		}
 /// <summary> Instantiates a new 'BitToByteOutput' object that uses 'out' as the
 /// underlying byte based output.
 ///
 /// </summary>
 /// <param name="out">The underlying byte based output
 ///
 /// </param>
 internal BitToByteOutput(ByteOutputBuffer out_Renamed)
 {
     this.out_Renamed = out_Renamed;
 }
Example #6
0
		/// <summary> Instantiates a new entropy coder engine, with the specified source of
		/// data, nominal block width and height.
		/// 
		/// <p>If the 'OPT_PRED_TERM' option is given then the MQ termination must
		/// be 'TERM_PRED_ER' or an exception is thrown.</p>
		/// 
		/// </summary>
		/// <param name="src">The source of data
		/// 
		/// </param>
		/// <param name="cbks">Code-block size specifications
		/// 
		/// </param>
		/// <param name="pss">Precinct partition specifications
		/// 
		/// </param>
		/// <param name="bms">By-pass mode specifications
		/// 
		/// </param>
		/// <param name="mqrs">MQ-reset specifications
		/// 
		/// </param>
		/// <param name="rts">Regular termination specifications
		/// 
		/// </param>
		/// <param name="css">Causal stripes specifications
		/// 
		/// </param>
		/// <param name="sss">Error resolution segment symbol use specifications
		/// 
		/// </param>
		/// <param name="lcs">Length computation specifications
		/// 
		/// </param>
		/// <param name="tts">Termination type specifications
		/// 
		/// </param>
		/// <seealso cref="MQCoder">
		/// 
		/// </seealso>
		public StdEntropyCoder(CBlkQuantDataSrcEnc src, CBlkSizeSpec cblks, PrecinctSizeSpec pss, StringSpec bms, StringSpec mqrs, StringSpec rts, StringSpec css, StringSpec sss, StringSpec lcs, StringSpec tts):base(src)
		{
			this.cblks = cblks;
			this.pss = pss;
			this.bms = bms;
			this.mqrs = mqrs;
			this.rts = rts;
			this.css = css;
			this.sss = sss;
			this.lcs = lcs;
			this.tts = tts;
			int maxCBlkWidth, maxCBlkHeight;
			int i; // Counter
			int nt; // The number of threads
			int tsl; // Size for thread structures
			
			// Get the biggest width/height for the code-blocks
			maxCBlkWidth = cblks.MaxCBlkWidth;
			maxCBlkHeight = cblks.MaxCBlkHeight;
			
            nt = Environment.ProcessorCount;
            /*
			// Get the number of threads to use, or default to one
			try
			{
				//UPGRADE_ISSUE: Method 'java.lang.System.getProperty' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'"
				nt = System.Int32.Parse(System_Renamed.getProperty(THREADS_PROP_NAME, DEF_THREADS_NUM));
				if (nt < 0)
					throw new System.FormatException();
			}
			catch (System.FormatException e)
			{
				throw new System.ArgumentException("Invalid number of threads " + "for " + "entropy coding in property " + THREADS_PROP_NAME);
			}
			*/

			// If we do timing create necessary structures
#if DO_TIMING
			time = new long[src.NumComps];
			// If we are timing make sure that 'finalize' gets called.
			//UPGRADE_ISSUE: Method 'java.lang.System.runFinalizersOnExit' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'"
			// CONVERSION PROBLEM?
            //System_Renamed.runFinalizersOnExit(true);
#endif			
			// If using multithreaded implementation get necessasry objects
			if (nt > 0)
			{
				FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Using multithreaded entropy coder " + "with " + nt + " compressor threads.");
				tsl = nt;
				tPool = new ThreadPool(nt, (System.Int32) SupportClass.ThreadClass.Current().Priority + THREADS_PRIORITY_INC, "StdEntropyCoder");
				idleComps = new System.Collections.ArrayList();
				completedComps = new System.Collections.ArrayList[src.NumComps];
				nBusyComps = new int[src.NumComps];
				finishedTileComponent = new bool[src.NumComps];
				for (i = src.NumComps - 1; i >= 0; i--)
				{
					completedComps[i] = new System.Collections.ArrayList();
				}
				for (i = 0; i < nt; i++)
				{
					idleComps.Add(new StdEntropyCoder.Compressor(this, i));
				}
			}
			else
			{
				tsl = 1;
				tPool = null;
				idleComps = null;
				completedComps = null;
				nBusyComps = null;
				finishedTileComponent = null;
			}
			
			// Allocate data structures
			outT = new ByteOutputBuffer[tsl];
			mqT = new MQCoder[tsl];
			boutT = new BitToByteOutput[tsl];
			stateT = new int[tsl][];
			for (int i2 = 0; i2 < tsl; i2++)
			{
				stateT[i2] = new int[(maxCBlkWidth + 2) * ((maxCBlkHeight + 1) / 2 + 2)];
			}
			symbufT = new int[tsl][];
			for (int i3 = 0; i3 < tsl; i3++)
			{
				symbufT[i3] = new int[maxCBlkWidth * (CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT * 2 + 2)];
			}
			ctxtbufT = new int[tsl][];
			for (int i4 = 0; i4 < tsl; i4++)
			{
				ctxtbufT[i4] = new int[maxCBlkWidth * (CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT * 2 + 2)];
			}
			distbufT = new double[tsl][];
			for (int i5 = 0; i5 < tsl; i5++)
			{
				distbufT[i5] = new double[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
			}
			ratebufT = new int[tsl][];
			for (int i6 = 0; i6 < tsl; i6++)
			{
				ratebufT[i6] = new int[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
			}
			istermbufT = new bool[tsl][];
			for (int i7 = 0; i7 < tsl; i7++)
			{
				istermbufT[i7] = new bool[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
			}
			srcblkT = new CBlkWTData[tsl];
			for (i = 0; i < tsl; i++)
			{
				outT[i] = new ByteOutputBuffer();
				mqT[i] = new MQCoder(outT[i], NUM_CTXTS, MQ_INIT);
			}
			precinctPartition = new bool[src.NumComps][];
			for (int i8 = 0; i8 < src.NumComps; i8++)
			{
				precinctPartition[i8] = new bool[src.getNumTiles()];
			}
			
			// Create the subband description for each component and each tile
			//Subband sb = null;
			Coord numTiles = null;
			int nc = NumComps;
			numTiles = src.getNumTiles(numTiles);
			initTileComp(getNumTiles(), nc);
			
			for (int c = 0; c < nc; c++)
			{
				for (int tY = 0; tY < numTiles.y; tY++)
				{
					for (int tX = 0; tX < numTiles.x; tX++)
					{
						precinctPartition[c][tIdx] = false;
					}
				}
			}
		}