public static void AndNotNull(XArray left, BitVector vector) { bool[] leftArray = (bool[])left.NullRows; if (leftArray == null) { return; } // Check how the arrays are configured and run the fastest loop possible for the configuration. if (left.Selector.Indices != null) { // Slow Path: Look up indices on both sides. ~55ms for 16M for (int i = 0; i < left.Count; ++i) { if (leftArray[left.Index(i)]) { vector.Clear(i); } } } else if (!left.Selector.IsSingleValue) { // Fastest Path: Contiguous Array to constant. ~15ms for 16M int zeroOffset = left.Selector.StartIndexInclusive; if (s_WhereSingleNative != null) { s_WhereSingleNative(leftArray, left.Selector.StartIndexInclusive, left.Selector.Count, (byte)CompareOperator.Equal, false, (byte)BooleanOperator.And, vector.Array, 0); } else { for (int i = left.Selector.StartIndexInclusive; i < left.Selector.EndIndexExclusive; ++i) { if (leftArray[i]) { vector.Clear(i - zeroOffset); } } } } else { // Single Static comparison. ~0.7ms for 16M [called every 10,240 rows] if (!leftArray[left.Selector.StartIndexInclusive]) { vector.None(); } } }
public BitVector TryGetValues(XArray keys, out ArraySelector rightSideSelector) { Allocator.AllocateToSize(ref _returnedVector, keys.Count); Allocator.AllocateToSize(ref _returnedIndicesBuffer, keys.Count); _returnedVector.None(); int countFound = 0; T[] keyArray = (T[])keys.Array; for (int i = 0; i < keys.Count; ++i) { int index = keys.Index(i); int foundAtIndex; if ((keys.HasNulls && keys.NullRows[index]) || !_dictionary.TryGetValue(keyArray[index], out foundAtIndex)) { _returnedVector.Clear(i); } else { _returnedVector.Set(i); _returnedIndicesBuffer[countFound++] = foundAtIndex; } } // Write out the indices of the joined rows for each value found rightSideSelector = ArraySelector.Map(_returnedIndicesBuffer, countFound); // Return the vector of which input rows matched return(_returnedVector); }
public void Remapper_Basics() { IRemapper <int> remapper = RemapperFactory.Build <int>(); ArraySlice <int> sample = new ArraySlice <int>(Enumerable.Range(2, 50).ToArray()); // Verify RemoveValues finds 0 and 1 unused in array with 2-52 BitVector unusedItems = new BitVector(true, 52); remapper.RemoveValues(sample, unusedItems); Assert.Equal("0, 1", string.Join(", ", unusedItems)); // Try RemoveValues with empty Vector (early return) unusedItems.Clear(); remapper.RemoveValues(sample, unusedItems); Assert.Empty(unusedItems); // Verify RemapAbove changes 50 and 51 to 100, 101 when instructed remapper.RemapAbove(sample, 50, new int[] { 100, 101 }); Assert.Equal(49, sample[47]); Assert.Equal(100, sample[48]); Assert.Equal(101, sample[49]); // Verify factory throws for unsupported types Assert.Throws <NotImplementedException>(() => RemapperFactory.Build <ulong>()); }
public void BitVector_DefaultTrue() { // Default = true vector BitVector vector = new BitVector(true, 32); HashSet <int> expected = new HashSet <int>(Enumerable.Range(0, 32)); Assert.Equal(32, vector.Count); VerifySame(expected, vector); // Clear every 4th value for (int i = 0; i < vector.Capacity; i += 4) { Assert.Equal(expected.Remove(i), vector.Remove(i)); } VerifySame(expected, vector); // Automatic growth with default vector.Remove(100); Assert.Equal(101, vector.Capacity); Assert.False(vector[100]); expected.UnionWith(Enumerable.Range(32, 100 - 32)); VerifySame(expected, vector); // SetAll vector.SetAll(true); Assert.Equal(vector.Capacity, vector.Count); Assert.True(vector[vector.Capacity]); vector.SetAll(false); Assert.True(0 == vector.Count); Assert.True(vector[vector.Capacity]); // SetAll, length exact multiple of 32. vector.Clear(); vector[3999] = false; vector.SetAll(false); Assert.False(vector[3999]); Assert.True(vector[4000]); vector.SetAll(true); Assert.True(vector[3999]); Assert.True(vector[4000]); }
protected void ReadRow() { // by default, fetch subset of primary fields only // everything else is fetched by FetchAdditionalFields for (var ordinal = 0; ordinal < CountOfMainFields; ordinal++) { var columnStore = DataContainer.ColumnStores[RowDataOrdinalToColumnStoreIndex[ordinal]]; if (columnStore.NotNulls.SafeGet(Position)) { BitVector.Set(RowData.NotNulls, ordinal); var indexInArray = RowData.FieldArrayIndexes[ordinal]; columnStore.AssignToDriverRow(Position, RowData, indexInArray); } else { BitVector.Clear(RowData.NotNulls, ordinal); } } }
public virtual void FetchAdditionalFields() { // get internal entity id DataContainer.DocumentKeys.GetAt(Position, RowData.InternalEntityId); // get other columns for (var ordinal = CountOfMainFields; ordinal < RowDataOrdinalToColumnStoreIndex.Length; ordinal++) { var columnStore = DataContainer.ColumnStores[RowDataOrdinalToColumnStoreIndex[ordinal]]; if (columnStore.NotNulls.SafeGet(Position)) { BitVector.Set(RowData.NotNulls, ordinal); var indexInArray = RowData.FieldArrayIndexes[ordinal]; columnStore.AssignToDriverRow(Position, RowData, indexInArray); } else { BitVector.Clear(RowData.NotNulls, ordinal); } } }
private void TestReadWrite(int size) { var data = CreateRandomBoolArray(size); var vectorData1 = new int[BitVector.GetArrayLength(size)]; for (var i = 0; i < data.Length; i++) { if (data[i]) { BitVector.Set(vectorData1, i); } else { BitVector.Clear(vectorData1, i); } } var vectorData2 = new int[vectorData1.Length]; using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream, Encoding.Default, true)) { BitVector.Write(vectorData1, size, writer); } Assert.AreEqual(BitVector.GetByteCount(size), stream.Length); stream.Seek(0, SeekOrigin.Begin); using (var reader = new BinaryReader(stream, Encoding.Default, true)) { BitVector.Read(vectorData2, size, reader); } Assert.AreEqual(stream.Position, stream.Length); Assert.IsTrue(vectorData1.SequenceEqual(vectorData2)); } }
private static void CompositeA(BitVector bitStream, int dataColumns, int compositeShiftCount) { // CC-A 2D component. int variant = 0; StringBuilder binaryString; BitVector bitPattern; int[] dataStream = new int[28]; Initialize928(); // Encode dataStream from bit stream int dataCodewords = Encode928(bitStream, dataStream); switch (dataColumns) { case 2: switch (dataCodewords) { case 6: variant = 0; break; case 8: variant = 1; break; case 9: variant = 2; break; case 11: variant = 3; break; case 12: variant = 4; break; case 14: variant = 5; break; case 17: variant = 6; break; } break; case 3: switch (dataCodewords) { case 8: variant = 7; break; case 10: variant = 8; break; case 12: variant = 9; break; case 14: variant = 10; break; case 17: variant = 11; break; } break; case 4: switch (dataCodewords) { case 8: variant = 12; break; case 11: variant = 13; break; case 14: variant = 14; break; case 17: variant = 15; break; case 20: variant = 16; break; } break; } int rowCount = PDF417Tables.CCAVariants[variant]; int eccCodewords = PDF417Tables.CCAVariants[17 + variant]; int offset = PDF417Tables.CCAVariants[34 + variant]; // Reed-Solomon error correction. int[] eccStream = new int[eccCodewords]; for (int i = 0; i < dataCodewords; i++) { int total = (dataStream[i] + eccStream[eccCodewords - 1]) % 929; for (int j = eccCodewords - 1; j > 0; j--) { eccStream[j] = (eccStream[j - 1] + 929 - (total * PDF417Tables.CCACoefficients[offset + j]) % 929) % 929; } eccStream[0] = (929 - (total * PDF417Tables.CCACoefficients[offset]) % 929) % 929; } for (int j = 0; j < eccCodewords; j++) { if (eccStream[j] != 0) { eccStream[j] = 929 - eccStream[j]; } } for (int i = eccCodewords - 1; i >= 0; i--) { dataStream[dataCodewords++] = eccStream[i]; } // Place data into table. int leftRAPStart = PDF417Tables.CCARAPTable[variant]; int centreRAPStart = PDF417Tables.CCARAPTable[variant + 17]; int rightRAPStart = PDF417Tables.CCARAPTable[variant + 34]; int startCluster = PDF417Tables.CCARAPTable[variant + 51] / 3; int leftRAP = leftRAPStart; int centreRAP = centreRAPStart; int rightRAP = rightRAPStart; int cluster = startCluster; // Cluster can be 0, 1 or 2 for cluster(0), cluster(3) and cluster(6). binaryString = new StringBuilder(); bitPattern = new BitVector(); int[] buffer = new int[dataColumns + 1]; for (int row = 0; row < rowCount; row++) { offset = 929 * cluster; for (int j = 0; j < buffer.Length; j++) { buffer[j] = 0; } for (int j = 0; j < dataColumns; j++) { buffer[j + 1] = dataStream[row * dataColumns + j]; } // Copy the data into code string. if (dataColumns != 3) { binaryString.Append(PDF417Tables.RowAddressPattern[leftRAP]); } binaryString.Append("1"); binaryString.Append(PDF417Tables.EncodingPatterns[offset + buffer[1]]); binaryString.Append("1"); if (dataColumns == 3) { binaryString.Append(PDF417Tables.CentreRowAddressPattern[centreRAP]); } if (dataColumns >= 2) { binaryString.Append("1"); binaryString.Append(PDF417Tables.EncodingPatterns[offset + buffer[2]]); binaryString.Append("1"); } if (dataColumns == 4) { binaryString.Append(PDF417Tables.CentreRowAddressPattern[centreRAP]); } if (dataColumns >= 3) { binaryString.Append("1"); binaryString.Append(PDF417Tables.EncodingPatterns[offset + buffer[3]]); binaryString.Append("1"); } if (dataColumns == 4) { binaryString.Append("1"); binaryString.Append(PDF417Tables.EncodingPatterns[offset + buffer[4]]); binaryString.Append("1"); } binaryString.Append(PDF417Tables.RowAddressPattern[rightRAP]); binaryString.Append("1"); // Stop. // The code string is a mixture of letters and numbers. bool latch = true; for (int i = 0; i < binaryString.Length; i++) { if ((binaryString[i] >= '0') && (binaryString[i] <= '9')) { int value = (int)(binaryString[i] - '0'); bitPattern.AppendBits((latch) ? 0xffff : 0, value); latch = !latch; } else { int position = PDF417Tables.PDFSet.IndexOf(binaryString[i]); if (position >= 0 && position < 32) { bitPattern.AppendBits(position, 5); } } } int bitPatternLength = bitPattern.SizeInBits; if (hostSymbol == Symbology.Code128) { if (linearWidth > bitPatternLength) { compositeShiftCount = (linearWidth - bitPatternLength) / 2; } else { compositeShiftCount = 0; } } byte[] rowData = new byte[bitPatternLength + compositeShiftCount]; for (int i = 0; i < bitPatternLength; i++) { rowData[i + compositeShiftCount] = bitPattern[i]; } SymbolData symbolData = new SymbolData(rowData, 2); encodedData.Insert(row, symbolData); // Clear data and set up RAPs and cluster for next row. binaryString.Clear(); bitPattern.Clear(); leftRAP++; centreRAP++; rightRAP++; cluster++; if (leftRAP == 53) { leftRAP = 1; } if (centreRAP == 53) { centreRAP = 1; } if (rightRAP == 53) { rightRAP = 1; } if (cluster == 3) { cluster = 0; } } }
private void ComputeImmediatePostDominators( ) { int len = m_nodes.Length; BitVector[] tmp = BitVector.AllocateBitVectors(len, len); for (int n = 0; n < len; n++) { // Tmp(n) := PostDomin(n) - {n} tmp[n].Assign(m_postDominance[n]); tmp[n].Clear(n); } for (int n = 0; n < len; n++) // Walk the basic blocks in pre-order. { // for each n in N do BitVector tmpN = tmp[n]; for (int s = 0; s < len; s++) { if (tmpN[s]) { // for each s in Tmp(n) do BitVector tmpS = tmp[s]; for (int t = 0; t < len; t++) { if (t != s && tmpN[t]) { // for each t in Tmp(n) - {s} do if (tmpS[t]) { // if t in Tmp(s) then Tmp(n) -= {t} tmpN.Clear(t); } } } } } } m_immediatePostDominators = new N[len]; for (int n = 0; n < len; n++) { bool fGot = false; foreach (int idom in tmp[n]) { CHECKS.ASSERT(fGot == false, "Internal failure, found more than one immediate post dominators"); m_immediatePostDominators[n] = m_nodes[idom]; fGot = true; } } }
private void TestRandomValuesSetter(int size) { var data = CreateRandomBoolArray(size); var array = new BitArray(size); var vector = new int[BitVector.GetArrayLength(size)]; // check both are false for (var i = 0; i < size; i++) { Assert.IsFalse(BitVector.Get(vector, i)); Assert.IsFalse(BitVector.SafeGet(vector, i)); Assert.IsFalse(array[i]); } // assign new values and check state immediately after assignment for (var i = 0; i < size; i++) { if (data[i]) { BitVector.Set(vector, i); } else { BitVector.Clear(vector, i); } array[i] = data[i]; Assert.AreEqual(array[i], BitVector.Get(vector, i)); Assert.AreEqual(array[i], BitVector.SafeGet(vector, i)); } // check all are equal after all setters for (var i = 0; i < size; i++) { Assert.AreEqual(array[i], BitVector.Get(vector, i)); Assert.AreEqual(array[i], BitVector.SafeGet(vector, i)); } // assign new values and check state immediately after assignment for (var i = 0; i < size; i++) { if (data[i]) { BitVector.SafeSet(vector, i); } else { BitVector.SafeClear(vector, i); } array[i] = data[i]; Assert.AreEqual(array[i], BitVector.Get(vector, i)); Assert.AreEqual(array[i], BitVector.SafeGet(vector, i)); } // check all are equal after all setters for (var i = 0; i < size; i++) { Assert.AreEqual(array[i], BitVector.Get(vector, i)); Assert.AreEqual(array[i], BitVector.SafeGet(vector, i)); } }
private static void CompositeC(BitVector bitStream, int dataColumns, int eccLevel) { // CC-C 2D component - byte compressed PDF417. int eccCodewords; int offset; StringBuilder codeString = new StringBuilder(); BitVector bitPattern = new BitVector(); List <int> dataStream = new List <int>(); dataStream.Add(0); // Reserve for length descriptor; dataStream.Add(920); // CC_C identifier. ProcessByte(dataStream, bitStream); dataStream[0] = dataStream.Count; eccCodewords = 1; for (int i = 0; i <= eccLevel; i++) { eccCodewords *= 2; } // Now take care of the Reed Solomon codes. if (eccCodewords == 2) { offset = 0; } else { offset = eccCodewords - 2; } int total = 0; int dataStreamLength = dataStream.Count; int[] eccStream = new int[eccCodewords]; for (int i = 0; i < dataStreamLength; i++) { total = (dataStream[i] + eccStream[eccCodewords - 1]) % 929; for (int j = eccCodewords - 1; j > 0; j--) { eccStream[j] = (eccStream[j - 1] + 929 - (total * PDF417Tables.Coefficients[offset + j]) % 929) % 929; } eccStream[0] = (929 - (total * PDF417Tables.Coefficients[offset]) % 929) % 929; } // Add the code words to the data stream. for (int i = eccCodewords - 1; i >= 0; i--) { dataStream.Add((eccStream[i] != 0) ? 929 - eccStream[i] : 0); } int rowCount = dataStream.Count / dataColumns; if (dataStream.Count % dataColumns != 0) { rowCount++; } int c1 = (rowCount - 1) / 3; int c2 = (eccLevel * 3) + ((rowCount - 1) % 3); int c3 = dataColumns - 1; // Encode each row. int[] buffer = new int[dataColumns + 2]; for (int row = 0; row < rowCount; row++) { for (int j = 0; j < dataColumns; j++) { buffer[j + 1] = dataStream[row * dataColumns + j]; } eccCodewords = (row / 3) * 30; switch (row % 3) { /* Follows this codePattern from US Patent 5,243,655: * Row 0: L0 (row #, # of rows) R0 (row #, # of columns) * Row 1: L1 (row #, security level) R1 (row #, # of rows) * Row 2: L2 (row #, # of columns) R2 (row #, security level) * Row 3: L3 (row #, # of rows) R3 (row #, # of columns) * etc. */ case 0: buffer[0] = eccCodewords + c1; buffer[dataColumns + 1] = eccCodewords + c3; break; case 1: buffer[0] = eccCodewords + c2; buffer[dataColumns + 1] = eccCodewords + c1; break; case 2: buffer[0] = eccCodewords + c3; buffer[dataColumns + 1] = eccCodewords + c2; break; } codeString.Append("+*"); // Start with a start char and a separator for (int j = 0; j <= dataColumns + 1; j++) { switch (row % 3) { case 1: offset = 929; break; case 2: offset = 1858; break; default: offset = 0; break; } codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[j]]); codeString.Append("*"); } codeString.Append("-"); for (int i = 0; i < codeString.Length; i++) { int position = PDF417Tables.PDFSet.IndexOf(codeString[i]); if (position >= 0 && position < 32) { bitPattern.AppendBits(position, 5); } else if (position == 32) { bitPattern.AppendBits(1, 2); } else if (position == 33) { bitPattern.AppendBits(0xff54, 16); } else { bitPattern.AppendBits(0x1fa29, 17); } } int size = bitPattern.SizeInBits; byte[] rowData = new byte[size]; for (int i = 0; i < size; i++) { rowData[i] = bitPattern[i]; } SymbolData symbolData = new SymbolData(rowData, 3); encodedData.Insert(row, symbolData); // Clear data ready for next row. codeString.Clear(); bitPattern.Clear(); } }
private static void CompositeB(BitVector bitStream, int dataColumns, int compositeShiftCount) { // CC-B 2D component. int variant = 0; StringBuilder codeString = new StringBuilder(); BitVector bitPattern = new BitVector(); List <int> dataStream = new List <int>(); // CC-B component requires codeword 920 in the first symbol character position (section 9a) dataStream.Add(920); ProcessByte(dataStream, bitStream); int dataStreamLength = dataStream.Count; // Calculate variant of the symbol to use and load values accordingly. if (dataColumns == 2) { variant = 13; if (dataStreamLength <= 33) { variant = 12; } if (dataStreamLength <= 29) { variant = 11; } if (dataStreamLength <= 24) { variant = 10; } if (dataStreamLength <= 19) { variant = 9; } if (dataStreamLength <= 13) { variant = 8; } if (dataStreamLength <= 8) { variant = 7; } } if (dataColumns == 3) { variant = 23; if (dataStreamLength <= 70) { variant = 22; } if (dataStreamLength <= 58) { variant = 21; } if (dataStreamLength <= 46) { variant = 20; } if (dataStreamLength <= 34) { variant = 19; } if (dataStreamLength <= 24) { variant = 18; } if (dataStreamLength <= 18) { variant = 17; } if (dataStreamLength <= 14) { variant = 16; } if (dataStreamLength <= 10) { variant = 15; } if (dataStreamLength <= 6) { variant = 14; } } if (dataColumns == 4) { variant = 34; if (dataStreamLength <= 108) { variant = 33; } if (dataStreamLength <= 90) { variant = 32; } if (dataStreamLength <= 72) { variant = 31; } if (dataStreamLength <= 54) { variant = 30; } if (dataStreamLength <= 39) { variant = 29; } if (dataStreamLength <= 30) { variant = 28; } if (dataStreamLength <= 24) { variant = 27; } if (dataStreamLength <= 18) { variant = 26; } if (dataStreamLength <= 12) { variant = 25; } if (dataStreamLength <= 8) { variant = 24; } } // Now we have the variant we can load the data - from here on the same as MicroPDF417 code. variant--; int rowCount = PDF417Tables.MicroVariants[variant + 34]; int eccCodewords = PDF417Tables.MicroVariants[variant + 68]; int dataCodewords = (dataColumns * rowCount) - eccCodewords; int padding = dataCodewords - dataStreamLength; int offset = PDF417Tables.MicroVariants[variant + 102]; // coefficient offset. // Add the padding. while (padding > 0) { dataStream.Add(900); padding--; } // Reed-Solomon error correction. dataStreamLength = dataStream.Count; int[] eccStream = new int[eccCodewords]; int total = 0; for (int i = 0; i < dataStreamLength; i++) { total = (dataStream[i] + eccStream[eccCodewords - 1]) % 929; for (int j = eccCodewords - 1; j > 0; j--) { eccStream[j] = (eccStream[j - 1] + 929 - (total * PDF417Tables.MicroCoefficients[offset + j]) % 929) % 929; } eccStream[0] = (929 - (total * PDF417Tables.MicroCoefficients[offset]) % 929) % 929; } for (int j = 0; j < eccCodewords; j++) { if (eccStream[j] != 0) { eccStream[j] = 929 - eccStream[j]; } } // Add the codewords to the data stream. for (int i = eccCodewords - 1; i >= 0; i--) { dataStream.Add(eccStream[i]); } dataStreamLength = dataStream.Count; // Get the RAP (Row Address Pattern) start values. int leftRAPStart = PDF417Tables.RowAddressTable[variant]; int centreRAPStart = PDF417Tables.RowAddressTable[variant + 34]; int rightRAPStart = PDF417Tables.RowAddressTable[variant + 68]; int startCluster = PDF417Tables.RowAddressTable[variant + 102] / 3; // That's all values loaded, get on with the encoding. int leftRAP = leftRAPStart; int centreRAP = centreRAPStart; int rightRAP = rightRAPStart; int cluster = startCluster; // Cluster can be 0, 1 or 2 for cluster(0), cluster(3) and cluster(6). int[] buffer = new int[dataColumns + 1]; for (int row = 0; row < rowCount; row++) { offset = 929 * cluster; for (int i = 0; i < buffer.Length; i++) { buffer[i] = 0; } for (int i = 0; i < dataColumns; i++) { buffer[i + 1] = dataStream[row * dataColumns + i]; } // Copy the data into code string codeString.Append(PDF417Tables.RowAddressPattern[leftRAP]); codeString.Append("1"); codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[1]]); codeString.Append("1"); if (dataColumns == 3) { codeString.Append(PDF417Tables.CentreRowAddressPattern[centreRAP]); } if (dataColumns >= 2) { codeString.Append("1"); codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[2]]); codeString.Append("1"); } if (dataColumns == 4) { codeString.Append(PDF417Tables.CentreRowAddressPattern[centreRAP]); } if (dataColumns >= 3) { codeString.Append("1"); codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[3]]); codeString.Append("1"); } if (dataColumns == 4) { codeString.Append("1"); codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[4]]); codeString.Append("1"); } codeString.Append(PDF417Tables.RowAddressPattern[rightRAP]); codeString.Append("1"); // Stop. // Code string is a mixture of letters and numbers. bool latch = true; for (int i = 0; i < codeString.Length; i++) { if ((codeString[i] >= '0') && (codeString[i] <= '9')) { int value = (int)(codeString[i] - '0'); bitPattern.AppendBits((latch) ? 0xffff : 0, value); latch = !latch; } else { int position = PDF417Tables.PDFSet.IndexOf(codeString[i]); if (position >= 0 && position < 32) { bitPattern.AppendBits(position, 5); } } } int bitPatternLength = bitPattern.SizeInBits; if (hostSymbol == Symbology.Code128) { if (linearWidth > bitPatternLength) { compositeShiftCount = (linearWidth - bitPatternLength) / 2; } else { compositeShiftCount = 0; } } byte[] rowData = new byte[bitPatternLength + compositeShiftCount]; for (int i = 0; i < bitPatternLength; i++) { rowData[i + compositeShiftCount] = bitPattern[i]; } SymbolData symbolData = new SymbolData(rowData, 2); encodedData.Insert(row, symbolData); // Clear data and set up RAPs and Cluster for next row. codeString.Clear(); bitPattern.Clear(); leftRAP++; centreRAP++; rightRAP++; cluster++; if (leftRAP == 53) { leftRAP = 1; } if (centreRAP == 53) { centreRAP = 1; } if (rightRAP == 53) { rightRAP = 1; } if (cluster == 3) { cluster = 0; } } }
public void TestBitVector() { var facit = new bool[9 * 64]; for (int r = 1; r < 8; r++) { var sz = r * 64; var bv = new BitVector(sz); facit.AsSpan().Clear(); for (int op = 0; op < 10000; op++) { var a = PRNG.Next(0, sz); var t = PRNG.Next(0, 14); switch (t) { case 0: bv.Clear(); facit.AsSpan().Clear(); break; case 1: bv.Set(a, true); facit[a] = true; break; case 2: case 3: bv.Set(a); facit[a] = true; break; case 4: case 5: case 6: bv[a] = true; facit[a] = true; break; case 7: case 8: bv.Clear(a); facit[a] = false; break; case 9: bv.Set(a, false); facit[a] = false; break; case 10: bv[a] = false; facit[a] = false; break; case 11: case 12: case 13: bv.Flip(a); if (facit[a]) { facit[a] = false; } else { facit[a] = true; } break; } // verify var cnt = 0; for (int i = 0; i < sz; i++) { Assert.AreEqual(facit[i], bv[i]); if (facit[i]) { cnt++; } } Assert.AreEqual(cnt, bv.CountSetBits()); } } }
private void PDF417() { int inputLength = barcodeData.Length; int modeListCount = 0; int offset; int eccLevel; int[,] modeList = new int[2, inputLength]; List <int> dataStream = new List <int>(); int[] eccStream; for (int i = 0; i < inputLength; i++) { int mode = GetMode(barcodeData[i]); if (i == 0) { modeList[1, modeListCount] = mode; modeList[0, modeListCount]++; } else { if (mode == modeList[1, modeListCount]) { modeList[0, modeListCount]++; } else { modeListCount++; modeList[1, modeListCount] = mode; modeList[0, modeListCount]++; } } } modeListCount++; SmoothPDF(ref modeListCount, modeList); // Compress the data. int dataIndex = 0; int dataStreamLength; for (int i = 0; i < modeListCount; i++) { switch (modeList[1, i]) { case TEXT: ProcessText(dataStream, dataIndex, modeList[0, i]); break; case BYTE: ProcessByte(dataStream, dataIndex, modeList[0, i]); break; case NUMBER: ProcessNumber(dataStream, dataIndex, modeList[0, i]); break; } dataIndex += modeList[0, i]; } // Now take care of the number of CWs per row. dataStreamLength = dataStream.Count; if (optionErrorCorrection < 0) { optionErrorCorrection = 6; if (dataStreamLength < 864) { optionErrorCorrection = 5; } if (dataStreamLength < 321) { optionErrorCorrection = 4; } if (dataStreamLength < 161) { optionErrorCorrection = 3; } if (dataStreamLength < 41) { optionErrorCorrection = 2; } } eccLevel = 1; for (int i = 1; i <= (optionErrorCorrection + 1); i++) { eccLevel *= 2; } if (optionDataColumns < 1) { optionDataColumns = (int)(0.5 + Math.Sqrt((dataStreamLength + eccLevel) / 3.0)); } if (((dataStreamLength + eccLevel) / optionDataColumns) > 90) { // Stop the symbol from becoming too high by increasing the columns. optionDataColumns = optionDataColumns + 1; } if ((dataStreamLength + eccLevel) > 928) { throw new InvalidDataLengthException("PDF417: Input data too long."); } if (((dataStreamLength + eccLevel) / optionDataColumns) > 90) { throw new InvalidDataLengthException("PDF417: Input data too long for specified number of columns."); } // Padding calculation. int totalLength = dataStreamLength + eccLevel + 1; int padding = 0; if ((totalLength / optionDataColumns) < 3) // A bar code must have at least three rows. { padding = (optionDataColumns * 3) - totalLength; } else { if ((totalLength % optionDataColumns) > 0) { padding = optionDataColumns - (totalLength % optionDataColumns); } } // Add the padding. while (padding > 0) { dataStream.Add(900); padding--; } // Insert the length descriptor. dataStream.Insert(0, dataStream.Count + 1); // We now take care of the Reed Solomon codes. if (optionErrorCorrection == 0) { offset = 0; } else { offset = eccLevel - 2; } dataStreamLength = dataStream.Count; eccStream = new int[eccLevel]; for (int i = 0; i < dataStreamLength; i++) { int total = (dataStream[i] + eccStream[eccLevel - 1]) % 929; for (int j = eccLevel - 1; j > 0; j--) { eccStream[j] = ((eccStream[j - 1] + 929) - (total * PDF417Tables.Coefficients[offset + j]) % 929) % 929; } eccStream[0] = (929 - (total * PDF417Tables.Coefficients[offset]) % 929) % 929; } // Add the code words to the data stream. for (int i = eccLevel - 1; i >= 0; i--) { dataStream.Add((eccStream[i] != 0) ? 929 - eccStream[i] : 0); } dataStreamLength = dataStream.Count; int rowCount = dataStreamLength / optionDataColumns; if (dataStreamLength % optionDataColumns != 0) { rowCount++; } int c1 = (rowCount - 1) / 3; int c2 = (optionErrorCorrection * 3) + ((rowCount - 1) % 3); int c3 = optionDataColumns - 1; // Encode each row. StringBuilder codeString = new StringBuilder(); BitVector bitPattern = new BitVector(); int[] buffer = new int[optionDataColumns + 2]; for (int row = 0; row < rowCount; row++) { for (int i = 0; i < buffer.Length; i++) { buffer[i] = 0; } for (int i = 0; i < optionDataColumns; i++) { buffer[i + 1] = dataStream[row * optionDataColumns + i]; } int errorCorrection = (row / 3) * 30; switch (row % 3) { /* Follows this codePattern from US Patent 5,243,655: * Row 0: L0 (row #, # of rows) R0 (row #, # of columns) * Row 1: L1 (row #, security level) R1 (row #, # of rows) * Row 2: L2 (row #, # of columns) R2 (row #, security level) * Row 3: L3 (row #, # of rows) R3 (row #, # of columns) * etc. */ case 0: buffer[0] = errorCorrection + c1; buffer[optionDataColumns + 1] = errorCorrection + c3; break; case 1: buffer[0] = errorCorrection + c2; buffer[optionDataColumns + 1] = errorCorrection + c1; break; case 2: buffer[0] = errorCorrection + c3; buffer[optionDataColumns + 1] = errorCorrection + c2; break; } codeString.Append("+*"); if (isTruncated) { // Truncated PDF - remove the last 5 characters. for (int j = 0; j <= optionDataColumns; j++) { switch (row % 3) { case 1: offset = 929; break; case 2: offset = 1858; break; default: offset = 0; break; } codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[j]]); codeString.Append("*"); } } else { // Normal PDF417 symbol. for (int j = 0; j <= optionDataColumns + 1; j++) { switch (row % 3) { case 1: offset = 929; break; case 2: offset = 1858; break; default: offset = 0; break; } codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[j]]); codeString.Append("*"); } codeString.Append("-"); } for (int i = 0; i < codeString.Length; i++) { int position = PDF417Tables.PDFSet.IndexOf(codeString[i]); if (position >= 0 && position < 32) { bitPattern.AppendBits(position, 5); } else if (position == 32) { bitPattern.AppendBits(1, 2); } else if (position == 33) { bitPattern.AppendBits(0xff54, 16); } else { bitPattern.AppendBits(0x1fa29, 17); } } int size = bitPattern.SizeInBits; byte[] rowData = new byte[size]; for (int i = 0; i < size; i++) { rowData[i] = bitPattern[i]; } SymbolData symbolData = new SymbolData(rowData, optionElementHeight); Symbol.Add(symbolData); // Clear data ready for next row. codeString.Clear(); bitPattern.Clear(); } }
/// <summary> /// Generate a Micro PDF barcode. /// </summary> private void MicroPDF417() { int inputLength = barcodeData.Length; int offset; int modeListCount = 0; List <int> dataStream = new List <int>(); int[] eccStream; // Encoding starts out the same as PDF417, so use the same code. int[,] modeList = new int[2, inputLength]; for (int i = 0; i < inputLength; i++) { int mode = GetMode(barcodeData[i]); if (i == 0) // First character. { modeList[1, modeListCount] = mode; modeList[0, modeListCount]++; } else { // Next character same mode. if (mode == modeList[1, modeListCount]) { modeList[0, modeListCount]++; } else { // Next character a different mode. modeListCount++; modeList[1, modeListCount] = mode; modeList[0, modeListCount]++; } } } modeListCount++; SmoothPDF(ref modeListCount, modeList); // Compress the data. int dataIndex = 0; int dataStreamLength; for (int i = 0; i < modeListCount; i++) { switch (modeList[1, i]) { case TEXT: ProcessText(dataStream, dataIndex, modeList[0, i]); break; case BYTE: ProcessByte(dataStream, dataIndex, modeList[0, i]); break; case NUMBER: ProcessNumber(dataStream, dataIndex, modeList[0, i]); break; } dataIndex += modeList[0, i]; } // // This is where it all changes! // dataStreamLength = dataStream.Count; if (dataStreamLength > 126) { throw new InvalidDataLengthException(); } if (optionDataColumns > 4) { optionDataColumns = 0; } // Now figure out which variant of the symbol to use and load values accordingly. int variant = 0; if ((optionDataColumns == 1) && (dataStreamLength > 20)) { // The user specified 1 column but the data doesn't fit - go to automatic optionDataColumns = 0; } if ((optionDataColumns == 2) && (dataStreamLength > 37)) { // The user specified 2 columns but the data doesn't fit - go to automatic optionDataColumns = 0; } if ((optionDataColumns == 3) && (dataStreamLength > 82)) { // The user specified 3 columns but the data doesn't fit - go to automatic optionDataColumns = 0; } if (optionDataColumns == 1) { variant = 6; if (dataStreamLength <= 16) { variant = 5; } if (dataStreamLength <= 12) { variant = 4; } if (dataStreamLength <= 10) { variant = 3; } if (dataStreamLength <= 7) { variant = 2; } if (dataStreamLength <= 4) { variant = 1; } } if (optionDataColumns == 2) { variant = 13; if (dataStreamLength <= 33) { variant = 12; } if (dataStreamLength <= 29) { variant = 11; } if (dataStreamLength <= 24) { variant = 10; } if (dataStreamLength <= 19) { variant = 9; } if (dataStreamLength <= 13) { variant = 8; } if (dataStreamLength <= 8) { variant = 7; } } if (optionDataColumns == 3) { // The user specified 3 columns and the data does fit variant = 23; if (dataStreamLength <= 70) { variant = 22; } if (dataStreamLength <= 58) { variant = 21; } if (dataStreamLength <= 46) { variant = 20; } if (dataStreamLength <= 34) { variant = 19; } if (dataStreamLength <= 24) { variant = 18; } if (dataStreamLength <= 18) { variant = 17; } if (dataStreamLength <= 14) { variant = 16; } if (dataStreamLength <= 10) { variant = 15; } if (dataStreamLength <= 6) { variant = 14; } } if (optionDataColumns == 4) { // The user specified 4 columns and the data does fit. variant = 34; if (dataStreamLength <= 108) { variant = 33; } if (dataStreamLength <= 90) { variant = 32; } if (dataStreamLength <= 72) { variant = 31; } if (dataStreamLength <= 54) { variant = 30; } if (dataStreamLength <= 39) { variant = 29; } if (dataStreamLength <= 30) { variant = 28; } if (dataStreamLength <= 24) { variant = 27; } if (dataStreamLength <= 18) { variant = 26; } if (dataStreamLength <= 12) { variant = 25; } if (dataStreamLength <= 8) { variant = 24; } } if (variant == 0) { // Let ZintNET choose automatically from all available variations. for (int i = 27; i >= 0; i--) { if (PDF417Tables.MicroAutoSize[i] >= dataStreamLength) { variant = PDF417Tables.MicroAutoSize[i + 28]; } } } // Now we have the variant we can load the data. variant--; optionDataColumns = PDF417Tables.MicroVariants[variant]; // columns int rowCount = PDF417Tables.MicroVariants[variant + 34]; // row Count int eccCodewords = PDF417Tables.MicroVariants[variant + 68]; // number of error correction CWs int dataCodewords = (optionDataColumns * rowCount) - eccCodewords; // number of data CWs int padding = dataCodewords - dataStreamLength; // amount of padding required offset = PDF417Tables.MicroVariants[variant + 102]; // coefficient offset // Add the padding while (padding > 0) { dataStream.Add(900); padding--; } // Reed-Solomon error correction dataStreamLength = dataStream.Count; eccStream = new int[eccCodewords]; for (int i = 0; i < dataStreamLength; i++) { int total = (dataStream[i] + eccStream[eccCodewords - 1]) % 929; for (int j = eccCodewords - 1; j > 0; j--) { eccStream[j] = ((eccStream[j - 1] + 929) - (total * PDF417Tables.MicroCoefficients[offset + j]) % 929) % 929; } eccStream[0] = (929 - (total * PDF417Tables.MicroCoefficients[offset]) % 929) % 929; } for (int j = 0; j < eccCodewords; j++) { if (eccStream[j] != 0) { eccStream[j] = 929 - eccStream[j]; } } // Add the reed-solomon codewords to the data stream. for (int i = eccCodewords - 1; i >= 0; i--) { dataStream.Add(eccStream[i]); } // RAP (Row Address Pattern) start values int leftRAPStart = PDF417Tables.RowAddressTable[variant]; int centreRAPStart = PDF417Tables.RowAddressTable[variant + 34]; int rightRAPStart = PDF417Tables.RowAddressTable[variant + 68]; int startCluster = PDF417Tables.RowAddressTable[variant + 102] / 3; // Start encoding. int leftRAP = leftRAPStart; int centreRAP = centreRAPStart; int rightRAP = rightRAPStart; int cluster = startCluster; // Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6). StringBuilder codeString = new StringBuilder(); BitVector bitPattern = new BitVector(); int[] buffer = new int[optionDataColumns + 1]; for (int row = 0; row < rowCount; row++) { for (int i = 0; i < buffer.Length; i++) { buffer[i] = 0; } for (int i = 0; i < optionDataColumns; i++) { buffer[i + 1] = dataStream[row * optionDataColumns + i]; } // Copy the data into code string. offset = 929 * cluster; codeString.Append(PDF417Tables.RowAddressPattern[leftRAP]); codeString.Append("1"); codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[1]]); codeString.Append("1"); if (optionDataColumns == 3) { codeString.Append(PDF417Tables.CentreRowAddressPattern[centreRAP]); } if (optionDataColumns >= 2) { codeString.Append("1"); codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[2]]); codeString.Append("1"); } if (optionDataColumns == 4) { codeString.Append(PDF417Tables.CentreRowAddressPattern[centreRAP]); } if (optionDataColumns >= 3) { codeString.Append("1"); codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[3]]); codeString.Append("1"); } if (optionDataColumns == 4) { codeString.Append("1"); codeString.Append(PDF417Tables.EncodingPatterns[offset + buffer[4]]); codeString.Append("1"); } codeString.Append(PDF417Tables.RowAddressPattern[rightRAP]); codeString.Append("1"); // Stop. // Now codeString is a mixture of letters and numbers bool latch = true; int value; for (int i = 0; i < codeString.Length; i++) { if ((codeString[i] >= '0') && (codeString[i] <= '9')) { value = (int)(codeString[i] - '0'); bitPattern.AppendBits((latch) ? 0xfff : 0, value); latch = !latch; } else { int position = PDF417Tables.PDFSet.IndexOf(codeString[i]); if (position >= 0 && position < 32) { bitPattern.AppendBits(position, 5); } } } int size = bitPattern.SizeInBits; byte[] rowData = new byte[size]; for (int i = 0; i < size; i++) { rowData[i] = bitPattern[i]; } SymbolData symbolData = new SymbolData(rowData, 2); Symbol.Add(symbolData); codeString.Clear(); bitPattern.Clear(); // Set up RAPs and Cluster for next row. leftRAP++; centreRAP++; rightRAP++; cluster++; if (leftRAP == 53) { leftRAP = 1; } if (centreRAP == 53) { centreRAP = 1; } if (rightRAP == 53) { rightRAP = 1; } if (cluster == 3) { cluster = 0; } } }
public void BitVectorTests_Basics() { BitVector vector = new BitVector(false, 260); HashSet <int> expected = new HashSet <int>(); // Empty vector vector.Trim(); VerifySame(expected, vector); Assert.Null(vector.Array); Assert.Equal(260, vector.Capacity); // Add every third item for (int i = 0; i < vector.Capacity; i += 3) { // True the first time Assert.Equal(expected.Add(i), vector.Add(i)); // False when already present Assert.Equal(expected.Add(i), vector.Add(i)); } VerifySame(expected, vector); // Remove every sixth item for (int i = 0; i < vector.Capacity; i += 6) { // True the first time Assert.Equal(expected.Remove(i), vector.Remove(i)); // False when already present Assert.Equal(expected.Remove(i), vector.Remove(i)); } VerifySame(expected, vector); // Contains for (int i = 0; i < vector.Capacity; ++i) { Assert.Equal(expected.Contains(i), vector.Contains(i)); } // Verify untyped enumerator, Reset() List <int> expectedList = new List <int>(expected); IEnumerator untyped = ((IEnumerable)vector).GetEnumerator(); int index = 0; while (untyped.MoveNext()) { Assert.Equal(expectedList[index], untyped.Current); index++; } untyped.Reset(); index = 0; while (untyped.MoveNext()) { Assert.Equal(expectedList[index], untyped.Current); index++; } // Automatic growth w/default (need 126 ints = 4,001 / 32 rounded up) vector.Add(4000); expected.Add(4000); Assert.Equal(4001, vector.Capacity); Assert.Equal(((4001 + 31) / 32), vector.Array?.Length ?? 0); VerifySame(expected, vector); // Clear vector.Clear(); Assert.Empty(vector); Assert.Equal(0, vector.Capacity); // UnionWith vector.UnionWith(expected); VerifySame(expected, vector); // ExceptWith vector.ExceptWith(expected); Assert.Empty(vector); // SetAll vector.Clear(); vector[100] = true; vector.SetAll(true); Assert.Equal(vector.Capacity, vector.Count); Assert.False(vector[vector.Capacity]); Assert.True(vector[vector.Capacity - 1]); vector.SetAll(false); Assert.Empty(vector); Assert.False(vector[vector.Capacity]); // SetAll (exact multiple of 32) vector.Clear(); vector[3999] = true; vector.SetAll(true); Assert.Equal(vector.Capacity, vector.Count); Assert.False(vector[vector.Capacity]); Assert.True(vector[vector.Capacity - 1]); vector.SetAll(false); Assert.Empty(vector); Assert.False(vector[vector.Capacity]); Assert.False(vector[vector.Capacity - 1]); }
public override void Clear() { _vector.Clear(); }