001/* 002 * Copyright 2007 ZXing authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.itextpdf.text.pdf.qrcode; 018 019/** 020 * <p>See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which 021 * data can be encoded to bits in the QR code standard.</p> 022 * 023 * @author Sean Owen 024 * @since 5.0.2 025 */ 026public final class Mode { 027 028 // No, we can't use an enum here. J2ME doesn't support it. 029 030 public static final Mode TERMINATOR = new Mode(new int[]{0, 0, 0}, 0x00, "TERMINATOR"); // Not really a mode... 031 public static final Mode NUMERIC = new Mode(new int[]{10, 12, 14}, 0x01, "NUMERIC"); 032 public static final Mode ALPHANUMERIC = new Mode(new int[]{9, 11, 13}, 0x02, "ALPHANUMERIC"); 033 public static final Mode STRUCTURED_APPEND = new Mode(new int[]{0, 0, 0}, 0x03, "STRUCTURED_APPEND"); // Not supported 034 public static final Mode BYTE = new Mode(new int[]{8, 16, 16}, 0x04, "BYTE"); 035 public static final Mode ECI = new Mode(null, 0x07, "ECI"); // character counts don't apply 036 public static final Mode KANJI = new Mode(new int[]{8, 10, 12}, 0x08, "KANJI"); 037 public static final Mode FNC1_FIRST_POSITION = new Mode(null, 0x05, "FNC1_FIRST_POSITION"); 038 public static final Mode FNC1_SECOND_POSITION = new Mode(null, 0x09, "FNC1_SECOND_POSITION"); 039 040 private final int[] characterCountBitsForVersions; 041 private final int bits; 042 private final String name; 043 044 private Mode(int[] characterCountBitsForVersions, int bits, String name) { 045 this.characterCountBitsForVersions = characterCountBitsForVersions; 046 this.bits = bits; 047 this.name = name; 048 } 049 050 /** 051 * @param bits four bits encoding a QR Code data mode 052 * @return {@link Mode} encoded by these bits 053 * @throws IllegalArgumentException if bits do not correspond to a known mode 054 */ 055 public static Mode forBits(int bits) { 056 switch (bits) { 057 case 0x0: 058 return TERMINATOR; 059 case 0x1: 060 return NUMERIC; 061 case 0x2: 062 return ALPHANUMERIC; 063 case 0x3: 064 return STRUCTURED_APPEND; 065 case 0x4: 066 return BYTE; 067 case 0x5: 068 return FNC1_FIRST_POSITION; 069 case 0x7: 070 return ECI; 071 case 0x8: 072 return KANJI; 073 case 0x9: 074 return FNC1_SECOND_POSITION; 075 default: 076 throw new IllegalArgumentException(); 077 } 078 } 079 080 /** 081 * @param version version in question 082 * @return number of bits used, in this QR Code symbol {@link Version}, to encode the 083 * count of characters that will follow encoded in this {@link Mode} 084 */ 085 public int getCharacterCountBits(Version version) { 086 if (characterCountBitsForVersions == null) { 087 throw new IllegalArgumentException("Character count doesn't apply to this mode"); 088 } 089 int number = version.getVersionNumber(); 090 int offset; 091 if (number <= 9) { 092 offset = 0; 093 } else if (number <= 26) { 094 offset = 1; 095 } else { 096 offset = 2; 097 } 098 return characterCountBitsForVersions[offset]; 099 } 100 101 public int getBits() { 102 return bits; 103 } 104 105 public String getName() { 106 return name; 107 } 108 109 public String toString() { 110 return name; 111 } 112 113}