/// <param name="val">ECI value</param> /// <returns><see cref="ECI"/> representing ECI of given value, or null if it is legal but unsupported</returns> /// <throws>ArgumentException if ECI value is invalid </throws> public static ECI getECIByValue(int val) { if (val < 0 || val > 999999) { throw new System.ArgumentException("Bad ECI value: " + val); } if (val < 900) { // Character set ECIs use 000000 - 000899 return(CharacterSetECI.getCharacterSetECIByValue(val)); } return(null); }
public bool AppendECI(int value) { encodeCurrentBytesIfAny(); CharacterSetECI characterSetECI = CharacterSetECI.getCharacterSetECIByValue(value); if (characterSetECI == null) { return(false); //throw FormatException.getFormatInstance(new RuntimeException("Unsupported ECI value " + value)); } currentCharset = CharacterSetECI.getEncoding(characterSetECI); return(true); }
/// <param name="value">ECI value /// </param> /// <returns> {@link ECI} representing ECI of given value, or null if it is legal but unsupported /// </returns> /// <throws> IllegalArgumentException if ECI value is invalid </throws> internal static ECI getECIByValue(int value_Renamed) { if (value_Renamed < 0 || value_Renamed > 999999) { throw new System.ArgumentException("Bad ECI value: " + value_Renamed); } if (value_Renamed < 900) { // Character set ECIs use 000000 - 000899 return(CharacterSetECI.getCharacterSetECIByValue(value_Renamed)); } return(null); }
/// <summary> /// Gets the string encoded in the aztec code bits /// </summary> /// <param name="correctedBits">The corrected bits.</param> /// <returns>the decoded string</returns> private static String getEncodedData(bool[] correctedBits) { var endIndex = correctedBits.Length; var latchTable = Table.UPPER; // table most recently latched to var shiftTable = Table.UPPER; // table to use for the next read var strTable = UPPER_TABLE; var index = 0; // Final decoded string result // (correctedBits-5) / 4 is an upper bound on the size (all-digit result) var result = new StringBuilder((correctedBits.Length - 5) / 4); // Intermediary buffer of decoded bytes, which is decoded into a string and flushed // when character encoding changes (ECI) or input ends. using (var decodedBytes = new System.IO.MemoryStream()) { var encoding = DEFAULT_ENCODING; while (index < endIndex) { if (shiftTable == Table.BINARY) { if (endIndex - index < 5) { break; } int length = readCode(correctedBits, index, 5); index += 5; if (length == 0) { if (endIndex - index < 11) { break; } length = readCode(correctedBits, index, 11) + 31; index += 11; } for (int charCount = 0; charCount < length; charCount++) { if (endIndex - index < 8) { index = endIndex; // Force outer loop to exit break; } int code = readCode(correctedBits, index, 8); decodedBytes.WriteByte((byte)code); index += 8; } // Go back to whatever mode we had been in shiftTable = latchTable; strTable = codeTables[shiftTable]; } else { int size = shiftTable == Table.DIGIT ? 4 : 5; if (endIndex - index < size) { break; } int code = readCode(correctedBits, index, size); index += size; String str = getCharacter(strTable, code); if ("FLG(n)".Equals(str)) { if (endIndex - index < 3) { break; } int n = readCode(correctedBits, index, 3); index += 3; // flush bytes, FLG changes state if (decodedBytes.Length > 0) { var byteArray = decodedBytes.ToArray(); result.Append(encoding.GetString(byteArray, 0, byteArray.Length)); decodedBytes.SetLength(0); } switch (n) { case 0: result.Append((char)29); // translate FNC1 as ASCII 29 break; case 7: throw new FormatException("FLG(7) is reserved and illegal"); default: // ECI is decimal integer encoded as 1-6 codes in DIGIT mode int eci = 0; if (endIndex - index < 4 * n) { break; } while (n-- > 0) { int nextDigit = readCode(correctedBits, index, 4); index += 4; if (nextDigit < 2 || nextDigit > 11) { throw new FormatException("Not a decimal digit"); } eci = eci * 10 + (nextDigit - 2); } CharacterSetECI charsetECI = CharacterSetECI.getCharacterSetECIByValue(eci); encoding = CharacterSetECI.getEncoding(charsetECI); if (encoding == null) { throw new FormatException("Encoding for ECI " + eci + " can't be resolved"); } break; } // Go back to whatever mode we had been in shiftTable = latchTable; strTable = codeTables[shiftTable]; } else if (str.StartsWith("CTRL_")) { // Table changes // ISO/IEC 24778:2008 prescribes ending a shift sequence in the mode from which it was invoked. // That's including when that mode is a shift. // Our test case dlusbs.png for issue #642 exercises that. latchTable = shiftTable; // Latch the current mode, so as to return to Upper after U/S B/S shiftTable = getTable(str[5]); strTable = codeTables[shiftTable]; if (str[6] == 'L') { latchTable = shiftTable; } } else { // Though stored as a table of strings for convenience, codes actually represent 1 or 2 *bytes*. #if (PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || WINDOWS_PHONE || NETFX_CORE || SILVERLIGHT) var b = StringUtils.PLATFORM_DEFAULT_ENCODING_T.GetBytes(str); #else var b = Encoding.ASCII.GetBytes(str); #endif decodedBytes.Write(b, 0, b.Length); // Go back to whatever mode we had been in shiftTable = latchTable; strTable = codeTables[shiftTable]; } } } if (decodedBytes.Length > 0) { var byteArray = decodedBytes.ToArray(); result.Append(encoding.GetString(byteArray, 0, byteArray.Length)); } } return(result.ToString()); }
internal static DecoderResult decode(byte[] bytes, Version version, ErrorCorrectionLevel ecLevel, IDictionary <DecodeHintType, object> hints) { var bits = new BitSource(bytes); var result = new StringBuilder(50); var byteSegments = new List <byte[]> (1); var symbolSequence = -1; var parityData = -1; try { CharacterSetECI currentCharacterSetECI = null; bool fc1InEffect = false; Mode mode; do { // While still another segment to read... if (bits.available() < 4) { // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here mode = Mode.TERMINATOR; } else { try { mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits } catch (ArgumentException) { return(null); } } if (mode != Mode.TERMINATOR) { if (mode == Mode.FNC1_FIRST_POSITION || mode == Mode.FNC1_SECOND_POSITION) { // We do little with FNC1 except alter the parsed result a bit according to the spec fc1InEffect = true; } else if (mode == Mode.STRUCTURED_APPEND) { if (bits.available() < 16) { return(null); } // not really supported; but sequence number and parity is added later to the result metadata // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue symbolSequence = bits.readBits(8); parityData = bits.readBits(8); } else if (mode == Mode.ECI) { // Count doesn't apply to ECI int value = parseECIValue(bits); currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value); if (currentCharacterSetECI == null) { return(null); } } else { // First handle Hanzi mode which does not start with character count if (mode == Mode.HANZI) { //chinese mode contains a sub set indicator right after mode indicator int subset = bits.readBits(4); int countHanzi = bits.readBits(mode.getCharacterCountBits(version)); if (subset == GB2312_SUBSET) { if (!decodeHanziSegment(bits, result, countHanzi)) { return(null); } } } else { // "Normal" QR code modes: // How many characters will follow, encoded in this mode? int count = bits.readBits(mode.getCharacterCountBits(version)); if (mode == Mode.NUMERIC) { if (!decodeNumericSegment(bits, result, count)) { return(null); } } else if (mode == Mode.ALPHANUMERIC) { if (!decodeAlphanumericSegment(bits, result, count, fc1InEffect)) { return(null); } } else if (mode == Mode.BYTE) { if (!decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints)) { return(null); } } else if (mode == Mode.KANJI) { if (!decodeKanjiSegment(bits, result, count)) { return(null); } } else { return(null); } } } } } while (mode != Mode.TERMINATOR); } catch (ArgumentException) { // from readBits() calls return(null); } #if WindowsCE var resultString = result.ToString().Replace("\n", "\r\n"); #else var resultString = result.ToString().Replace("\r\n", "\n").Replace("\n", Environment.NewLine); #endif return(new DecoderResult(bytes, resultString, byteSegments.Count == 0 ? null : byteSegments, ecLevel == null ? null : ecLevel.ToString(), symbolSequence, parityData)); }
internal static DecoderResult decode(int[] codewords, String ecLevel) { var result = new StringBuilder(codewords.Length * 2); // Get compaction mode int codeIndex = 1; int code = codewords[codeIndex++]; var resultMetadata = new PDF417ResultMetadata(); Encoding encoding = null; while (codeIndex < codewords[0]) { switch (code) { case TEXT_COMPACTION_MODE_LATCH: codeIndex = textCompaction(codewords, codeIndex, result); break; case BYTE_COMPACTION_MODE_LATCH: case BYTE_COMPACTION_MODE_LATCH_6: codeIndex = byteCompaction(code, codewords, encoding ?? (encoding = getEncoding(PDF417HighLevelEncoder.DEFAULT_ENCODING_NAME)), codeIndex, result); break; case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: result.Append((char)codewords[codeIndex++]); break; case NUMERIC_COMPACTION_MODE_LATCH: codeIndex = numericCompaction(codewords, codeIndex, result); break; case ECI_CHARSET: var charsetECI = CharacterSetECI.getCharacterSetECIByValue(codewords[codeIndex++]); encoding = getEncoding(charsetECI.EncodingName); break; case ECI_GENERAL_PURPOSE: // Can't do anything with generic ECI; skip its 2 characters codeIndex += 2; break; case ECI_USER_DEFINED: // Can't do anything with user ECI; skip its 1 character codeIndex++; break; case BEGIN_MACRO_PDF417_CONTROL_BLOCK: codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata); break; case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: case MACRO_PDF417_TERMINATOR: // Should not see these outside a macro block return(null); default: // Default to text compaction. During testing numerous barcodes // appeared to be missing the starting mode. In these cases defaulting // to text compaction seems to work. codeIndex--; codeIndex = textCompaction(codewords, codeIndex, result); break; } if (codeIndex < 0) { return(null); } if (codeIndex < codewords.Length) { code = codewords[codeIndex++]; } else { return(null); } } if (result.Length == 0) { return(null); } var decoderResult = new DecoderResult(null, result.ToString(), null, ecLevel); decoderResult.Other = resultMetadata; return(decoderResult); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET: //ORIGINAL LINE: static com.google.zxing.common.DecoderResult decode(byte[] bytes, Version version, ErrorCorrectionLevel ecLevel, java.util.Map<com.google.zxing.DecodeHintType,?> hints) throws com.google.zxing.FormatException internal static DecoderResult decode(sbyte[] bytes, Version version, ErrorCorrectionLevel ecLevel, IDictionary <DecodeHintType, object> hints) { BitSource bits = new BitSource(bytes); StringBuilder result = new StringBuilder(50); IList <sbyte[]> byteSegments = new List <sbyte[]>(1); try { CharacterSetECI currentCharacterSetECI = null; bool fc1InEffect = false; Mode mode; do { // While still another segment to read... if (bits.available() < 4) { // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here mode = Mode.TERMINATOR; } else { mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits } if (mode != Mode.TERMINATOR) { if (mode == Mode.FNC1_FIRST_POSITION || mode == Mode.FNC1_SECOND_POSITION) { // We do little with FNC1 except alter the parsed result a bit according to the spec fc1InEffect = true; } else if (mode == Mode.STRUCTURED_APPEND) { if (bits.available() < 16) { throw FormatException.FormatInstance; } // not really supported; all we do is ignore it // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue bits.readBits(16); } else if (mode == Mode.ECI) { // Count doesn't apply to ECI int value = parseECIValue(bits); currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value); if (currentCharacterSetECI == null) { throw FormatException.FormatInstance; } } else { // First handle Hanzi mode which does not start with character count if (mode == Mode.HANZI) { //chinese mode contains a sub set indicator right after mode indicator int subset = bits.readBits(4); int countHanzi = bits.readBits(mode.getCharacterCountBits(version)); if (subset == GB2312_SUBSET) { decodeHanziSegment(bits, result, countHanzi); } } else { // "Normal" QR code modes: // How many characters will follow, encoded in this mode? int count = bits.readBits(mode.getCharacterCountBits(version)); if (mode == Mode.NUMERIC) { decodeNumericSegment(bits, result, count); } else if (mode == Mode.ALPHANUMERIC) { decodeAlphanumericSegment(bits, result, count, fc1InEffect); } else if (mode == Mode.BYTE) { decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints); } else if (mode == Mode.KANJI) { decodeKanjiSegment(bits, result, count); } else { throw FormatException.FormatInstance; } } } } } while (mode != Mode.TERMINATOR); } catch (System.ArgumentException iae) { // from readBits() calls throw FormatException.FormatInstance; } return(new DecoderResult(bytes, result.ToString(), byteSegments.Count == 0 ? null : byteSegments, ecLevel == null ? null : ecLevel.ToString())); }