Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix, including areas used for finder patterns, timing patterns, etc. These areas should be unused after the point they are unmasked anyway.

Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position and j is row position. In fact, as the text says, i is row position and j is column position.

Ejemplo n.º 1
0
        /**
         * Revert the mask removal done while reading the code words. The bit matrix should revert to its original state.
         */
        internal void remask()
        {
            if (parsedFormatInfo == null)
            {
                return; // We have no format information, and have no data mask
            }
            int dimension = bitMatrix.Height;

            DataMask.unmaskBitMatrix(parsedFormatInfo.DataMask, bitMatrix, dimension);
        }
Ejemplo n.º 2
0
        /**
         * Revert the mask removal done while reading the code words. The bit matrix should revert to its original state.
         */
        internal void remask()
        {
            if (parsedFormatInfo == null)
            {
                return; // We have no format information, and have no data mask
            }
            DataMask dataMask  = DataMask.forReference(parsedFormatInfo.DataMask);
            int      dimension = bitMatrix.Height;

            dataMask.unmaskBitMatrix(bitMatrix, dimension);
        }
Ejemplo n.º 3
0
        /// <summary> <p>Reads the bits in the {@link BitMatrix} representing the finder pattern in the
        /// correct order in order to reconstruct the codewords bytes contained within the
        /// QR Code.</p>
        ///
        /// </summary>
        /// <returns> bytes encoded within the QR Code
        /// </returns>
        /// <throws>  ReaderException if the exact number of bytes expected is not read </throws>
        internal byte[] readCodewords()
        {
            FormatInformation formatInfo = readFormatInformation();

            if (formatInfo == null)
            {
                return(null);
            }
            Version version = readVersion();

            if (version == null)
            {
                return(null);
            }

            // Get the data mask for the format used in this QR Code. This will exclude
            // some bits from reading as we wind through the bit matrix.
            int dimension = bitMatrix.Height;

            DataMask.unmaskBitMatrix(formatInfo.DataMask, bitMatrix, dimension);

            BitMatrix functionPattern = version.buildFunctionPattern();

            bool readingUp = true;

            byte[] result       = new byte[version.TotalCodewords];
            int    resultOffset = 0;
            int    currentByte  = 0;
            int    bitsRead     = 0;

            // Read columns in pairs, from right to left
            for (int j = dimension - 1; j > 0; j -= 2)
            {
                if (j == 6)
                {
                    // Skip whole column with vertical alignment pattern;
                    // saves time and makes the other code proceed more cleanly
                    j--;
                }
                // Read alternatingly from bottom to top then top to bottom
                for (int count = 0; count < dimension; count++)
                {
                    int i = readingUp ? dimension - 1 - count : count;
                    for (int col = 0; col < 2; col++)
                    {
                        // Ignore bits covered by the function pattern
                        if (!functionPattern[j - col, i])
                        {
                            // Read a bit
                            bitsRead++;
                            currentByte <<= 1;
                            if (bitMatrix[j - col, i])
                            {
                                currentByte |= 1;
                            }
                            // If we've made a whole byte, save it off
                            if (bitsRead == 8)
                            {
                                result[resultOffset++] = (byte)currentByte;
                                bitsRead    = 0;
                                currentByte = 0;
                            }
                        }
                    }
                }
                readingUp ^= true; // readingUp = !readingUp; // switch directions
            }
            if (resultOffset != version.TotalCodewords)
            {
                return(null);
            }
            return(result);
        }