public ReedSolomon(GenericGF galoisField, int correctionBytes)
 {
     _messageLength = galoisField.Size - 1;
     _correctionLength = correctionBytes;
     _informationLength = _messageLength - _correctionLength;
     _reedSolomonEncoder = new ReedSolomonEncoder(galoisField);
     _reedSolomonDecoder = new ReedSolomonDecoder(galoisField);
     _simpleRsDecoder = new SimpleRSDecoder();
 }
 public ReedSolomon(int correctionBytes)
 {
     var galoisField = GenericGF.DATA_MATRIX_FIELD_256;
     _messageLength = galoisField.Size - 1;
     _correctionLength = correctionBytes;
     _informationLength = _messageLength - _correctionLength;
     _reedSolomonEncoder = new ReedSolomonEncoder(galoisField);
     _reedSolomonDecoder = new ReedSolomonDecoder(galoisField);
     _simpleRsDecoder = new SimpleRSDecoder();
 }
Exemplo n.º 3
0
        private static void testDecoder(GenericGF field, int[] dataWords, int[] ecWords)
        {
            ReedSolomonDecoder decoder = new ReedSolomonDecoder(field);

            int[]  message    = new int[dataWords.Length + ecWords.Length];
            int    maxErrors  = ecWords.Length / 2;
            Random random     = getPseudoRandom();
            int    iterations = field.Size > 256 ? 1 : DECODER_TEST_ITERATIONS;

            for (int j = 0; j < iterations; j++)
            {
                for (int i = 0; i < ecWords.Length; i++)
                {
                    if (i > 10 && i < ecWords.Length / 2 - 10)
                    {
                        // performance improvement - skip intermediate cases in long-running tests
                        i += ecWords.Length / 10;
                    }
                    Array.Copy(dataWords, 0, message, 0, dataWords.Length);
                    Array.Copy(ecWords, 0, message, dataWords.Length, ecWords.Length);
                    corrupt(message, i, random, field.Size);
                    if (!decoder.decode(message, ecWords.Length))
                    {
                        // fail only if maxErrors exceeded
                        Assert.IsTrue(i > maxErrors, "Decode in " + field + " (" + dataWords.Length + ',' + ecWords.Length + ") failed at " + i);
                        // else stop
                        break;
                    }
                    if (i < maxErrors)
                    {
                        assertDataEquals("Decode in " + field + " (" + dataWords.Length + ',' + ecWords.Length + ") failed at " +
                                         i + " errors",
                                         dataWords,
                                         message);
                    }
                }
            }
        }
Exemplo n.º 4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Decoder"/> class.
 /// </summary>
 public Decoder()
 {
    rsDecoder = new ReedSolomonDecoder(GenericGF.DATA_MATRIX_FIELD_256);
 }
Exemplo n.º 5
0
      /// <summary>
      /// Corrects the parameter bits using Reed-Solomon algorithm
      /// </summary>
      /// <param name="parameterData">paremeter bits</param>
      /// <param name="compact">compact true if this is a compact Aztec code</param>
      /// <returns></returns>
      private static bool correctParameterData(bool[] parameterData, bool compact)
      {
         int numCodewords;
         int numDataCodewords;

         if (compact)
         {
            numCodewords = 7;
            numDataCodewords = 2;
         }
         else
         {
            numCodewords = 10;
            numDataCodewords = 4;
         }

         int numECCodewords = numCodewords - numDataCodewords;
         int[] parameterWords = new int[numCodewords];

         const int codewordSize = 4;
         for (int i = 0; i < numCodewords; i++)
         {
            int flag = 1;
            for (int j = 1; j <= codewordSize; j++)
            {
               if (parameterData[codewordSize * i + codewordSize - j])
               {
                  parameterWords[i] += flag;
               }
               flag <<= 1;
            }
         }

         var rsDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM);
         if (!rsDecoder.decode(parameterWords, numECCodewords))
            return false;

         for (int i = 0; i < numDataCodewords; i++)
         {
            int flag = 1;
            for (int j = 1; j <= codewordSize; j++)
            {
               parameterData[i * codewordSize + codewordSize - j] = (parameterWords[i] & flag) == flag;
               flag <<= 1;
            }
         }

         return true;
      }
Exemplo n.º 6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Decoder"/> class.
 /// </summary>
 public Decoder()
 {
    rsDecoder = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256);
 }
Exemplo n.º 7
0
      /// <summary>
      ///Performs RS error correction on an array of bits.
      /// </summary>
      /// <param name="rawbits">The rawbits.</param>
      /// <returns>the corrected array</returns>
      private bool[] correctBits(bool[] rawbits)
      {
         GenericGF gf;
         int codewordSize;

         if (ddata.NbLayers <= 2)
         {
            codewordSize = 6;
            gf = GenericGF.AZTEC_DATA_6;
         }
         else if (ddata.NbLayers <= 8)
         {
            codewordSize = 8;
            gf = GenericGF.AZTEC_DATA_8;
         }
         else if (ddata.NbLayers <= 22)
         {
            codewordSize = 10;
            gf = GenericGF.AZTEC_DATA_10;
         }
         else
         {
            codewordSize = 12;
            gf = GenericGF.AZTEC_DATA_12;
         }

         int numDataCodewords = ddata.NbDatablocks;
         int numCodewords = rawbits.Length/codewordSize;
         if (numCodewords < numDataCodewords)
            return null;

         int offset = rawbits.Length%codewordSize;
         int numECCodewords = numCodewords - numDataCodewords;

         int[] dataWords = new int[numCodewords];
         for (int i = 0; i < numCodewords; i++, offset += codewordSize)
         {
            dataWords[i] = readCode(rawbits, offset, codewordSize);
         }

         var rsDecoder = new ReedSolomonDecoder(gf);
         if (!rsDecoder.decode(dataWords, numECCodewords))
            return null;

         // Now perform the unstuffing operation.
         // First, count how many bits are going to be thrown out as stuffing
         int mask = (1 << codewordSize) - 1;
         int stuffedBits = 0;
         for (int i = 0; i < numDataCodewords; i++)
         {
            int dataWord = dataWords[i];
            if (dataWord == 0 || dataWord == mask)
            {
               return null;
            }
            else if (dataWord == 1 || dataWord == mask - 1)
            {
               stuffedBits++;
            }
         }
         // Now, actually unpack the bits and remove the stuffing
         bool[] correctedBits = new bool[numDataCodewords*codewordSize - stuffedBits];
         int index = 0;
         for (int i = 0; i < numDataCodewords; i++)
         {
            int dataWord = dataWords[i];
            if (dataWord == 1 || dataWord == mask - 1)
            {
               // next codewordSize-1 bits are all zeros or all ones
               SupportClass.Fill(correctedBits, index, index + codewordSize - 1, dataWord > 1);
               index += codewordSize - 1;
            }
            else
            {
               for (int bit = codewordSize - 1; bit >= 0; --bit)
               {
                  correctedBits[index++] = (dataWord & (1 << bit)) != 0;
               }
            }
         }

         if (index != correctedBits.Length)
            return null;

         return correctedBits;
      }
Exemplo n.º 8
0
      /// <summary>
      /// Corrects the parameter bits using Reed-Solomon algorithm
      /// </summary>
      /// <param name="parameterData">paremeter bits</param>
      /// <param name="compact">compact true if this is a compact Aztec code</param>
      /// <returns></returns>
      private static int getCorrectedParameterData(long parameterData, bool compact)
      {
         int numCodewords;
         int numDataCodewords;

         if (compact)
         {
            numCodewords = 7;
            numDataCodewords = 2;
         }
         else
         {
            numCodewords = 10;
            numDataCodewords = 4;
         }

         int numECCodewords = numCodewords - numDataCodewords;
         int[] parameterWords = new int[numCodewords];

         for (int i = numCodewords - 1; i >= 0; --i)
         {
            parameterWords[i] = (int)parameterData & 0xF;
            parameterData >>= 4;
         }

         var rsDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM);
         if (!rsDecoder.decode(parameterWords, numECCodewords))
            return -1;

         // Toss the error correction.  Just return the data as an integer
         int result = 0;
         for (int i = 0; i < numDataCodewords; i++)
         {
            result = (result << 4) + parameterWords[i];
         }
         return result;
      }
Exemplo n.º 9
0
 /// <summary>
 /// Decoder() constructor
 /// </summary>
 public Decoder()
 {
     rsDecoder = new ReedSolomonDecoder(GenericGF.MAXICODE_FIELD_64);
 }
Exemplo n.º 10
0
      /// <summary>
      /// performs RS error correction on an array of bits
      /// </summary>
      /// <param name="rawbits">The rawbits.</param>
      /// <returns>the corrected array</returns>
      /// <exception cref="FormatException">if the input contains too many errors</exception>
      private bool[] correctBits(bool[] rawbits)
      {
         GenericGF gf;

         if (ddata.NbLayers <= 2)
         {
            codewordSize = 6;
            gf = GenericGF.AZTEC_DATA_6;
         }
         else if (ddata.NbLayers <= 8)
         {
            codewordSize = 8;
            gf = GenericGF.AZTEC_DATA_8;
         }
         else if (ddata.NbLayers <= 22)
         {
            codewordSize = 10;
            gf = GenericGF.AZTEC_DATA_10;
         }
         else
         {
            codewordSize = 12;
            gf = GenericGF.AZTEC_DATA_12;
         }

         int numDataCodewords = ddata.NbDatablocks;
         int numECCodewords;
         int offset;

         if (ddata.Compact)
         {
            offset = NB_BITS_COMPACT[ddata.NbLayers] - numCodewords * codewordSize;
            numECCodewords = NB_DATABLOCK_COMPACT[ddata.NbLayers] - numDataCodewords;
         }
         else
         {
            offset = NB_BITS[ddata.NbLayers] - numCodewords * codewordSize;
            numECCodewords = NB_DATABLOCK[ddata.NbLayers] - numDataCodewords;
         }

         int[] dataWords = new int[numCodewords];
         for (int i = 0; i < numCodewords; i++)
         {
            int flag = 1;
            for (int j = 1; j <= codewordSize; j++)
            {
               if (rawbits[codewordSize * i + codewordSize - j + offset])
               {
                  dataWords[i] += flag;
               }
               flag <<= 1;
            }

            //if (dataWords[i] >= flag) {
            //  flag++;
            //}
         }

         var rsDecoder = new ReedSolomonDecoder(gf);
         if (!rsDecoder.decode(dataWords, numECCodewords))
            return null;

         offset = 0;
         invertedBitCount = 0;

         bool[] correctedBits = new bool[numDataCodewords * codewordSize];
         for (int i = 0; i < numDataCodewords; i++)
         {

            bool seriesColor = false;
            int seriesCount = 0;
            int flag = 1 << (codewordSize - 1);

            for (int j = 0; j < codewordSize; j++)
            {

               bool color = (dataWords[i] & flag) == flag;

               if (seriesCount == codewordSize - 1)
               {

                  if (color == seriesColor)
                  {
                     //bit must be inverted
                     return null;
                  }

                  seriesColor = false;
                  seriesCount = 0;
                  offset++;
                  invertedBitCount++;
               }
               else
               {

                  if (seriesColor == color)
                  {
                     seriesCount++;
                  }
                  else
                  {
                     seriesCount = 1;
                     seriesColor = color;
                  }

                  correctedBits[i * codewordSize + j - offset] = color;

               }

               flag = (int)((uint)flag >> 1); // flag >>>= 1;
            }
         }

         return correctedBits;
      }