OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
181 ilm 1
/*
2
 * Copyright 2014 Robin Stuart
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
 * in compliance with the License. You may obtain a copy of the License at
6
 *
7
 * http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software distributed under the License
10
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
 * or implied. See the License for the specific language governing permissions and limitations under
12
 * the License.
13
 */
14
package uk.org.okapibarcode.backend;
15
 
16
/**
17
 * <p>
18
 * Implements the Aztec Runes bar code symbology according to ISO/IEC 24778:2008 Annex A.
19
 *
20
 * <p>
21
 * Aztec Runes is a fixed-size matrix symbology which can encode whole integer values between 0 and
22
 * 255.
23
 *
24
 * @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
25
 */
26
public class AztecRune extends Symbol {
27
 
28
    private static final int[] BIT_PLACEMENT_MAP = { 1, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 1, 0, 0, 0, 0, 0, 0, 0, 1, 9, 28, 1, 0, 1, 1, 1, 1, 1, 0, 1, 10, 27, 1, 0, 1,
29
            0, 0, 0, 1, 0, 1, 11, 26, 1, 0, 1, 0, 1, 0, 1, 0, 1, 12, 25, 1, 0, 1, 0, 0, 0, 1, 0, 1, 13, 24, 1, 0, 1, 1, 1, 1, 1, 0, 1, 14, 23, 1, 0, 0, 0, 0, 0, 0, 0, 1, 15, 0, 1, 1, 1, 1, 1, 1, 1, 1,
30
            1, 1, 0, 0, 22, 21, 20, 19, 18, 17, 16, 0, 0 };
31
 
32
    @Override
33
    protected void encode() {
34
 
35
        if (!this.content.matches("[0-9]+")) {
36
            throw new OkapiException("Invalid input data");
37
        }
38
 
39
        int decimalValue = 0;
40
        switch (this.content.length()) {
41
        case 1:
42
            decimalValue = this.content.charAt(0) - '0';
43
            break;
44
        case 2:
45
            decimalValue = 10 * (this.content.charAt(0) - '0');
46
            decimalValue += this.content.charAt(1) - '0';
47
            break;
48
        case 3:
49
            decimalValue = 100 * (this.content.charAt(0) - '0');
50
            decimalValue += 10 * (this.content.charAt(1) - '0');
51
            decimalValue += this.content.charAt(2) - '0';
52
            break;
53
        default:
54
            throw new OkapiException("Input too large");
55
        }
56
 
57
        if (decimalValue > 255) {
58
            throw new OkapiException("Input too large");
59
        }
60
 
61
        final StringBuilder binaryDataStream = new StringBuilder(28);
62
        for (int i = 0x80; i > 0; i = i >> 1) {
63
            if ((decimalValue & i) != 0) {
64
                binaryDataStream.append('1');
65
            } else {
66
                binaryDataStream.append('0');
67
            }
68
        }
69
 
70
        final int[] dataCodeword = new int[3];
71
        dataCodeword[0] = 0;
72
        dataCodeword[1] = 0;
73
 
74
        for (int i = 0; i < 2; i++) {
75
            if (binaryDataStream.charAt(i * 4) == '1') {
76
                dataCodeword[i] += 8;
77
            }
78
            if (binaryDataStream.charAt(i * 4 + 1) == '1') {
79
                dataCodeword[i] += 4;
80
            }
81
            if (binaryDataStream.charAt(i * 4 + 2) == '1') {
82
                dataCodeword[i] += 2;
83
            }
84
            if (binaryDataStream.charAt(i * 4 + 3) == '1') {
85
                dataCodeword[i] += 1;
86
            }
87
        }
88
 
89
        final int[] errorCorrectionCodeword = new int[6];
90
 
91
        final ReedSolomon rs = new ReedSolomon();
92
        rs.init_gf(0x13);
93
        rs.init_code(5, 1);
94
        rs.encode(2, dataCodeword);
95
 
96
        for (int i = 0; i < 5; i++) {
97
            errorCorrectionCodeword[i] = rs.getResult(i);
98
        }
99
 
100
        for (int i = 0; i < 5; i++) {
101
            if ((errorCorrectionCodeword[4 - i] & 0x08) != 0) {
102
                binaryDataStream.append('1');
103
            } else {
104
                binaryDataStream.append('0');
105
            }
106
            if ((errorCorrectionCodeword[4 - i] & 0x04) != 0) {
107
                binaryDataStream.append('1');
108
            } else {
109
                binaryDataStream.append('0');
110
            }
111
            if ((errorCorrectionCodeword[4 - i] & 0x02) != 0) {
112
                binaryDataStream.append('1');
113
            } else {
114
                binaryDataStream.append('0');
115
            }
116
            if ((errorCorrectionCodeword[4 - i] & 0x01) != 0) {
117
                binaryDataStream.append('1');
118
            } else {
119
                binaryDataStream.append('0');
120
            }
121
        }
122
 
123
        final StringBuilder reversedBinaryDataStream = new StringBuilder(28);
124
        for (int i = 0; i < binaryDataStream.length(); i++) {
125
            if ((i & 1) == 0) {
126
                if (binaryDataStream.charAt(i) == '0') {
127
                    reversedBinaryDataStream.append('1');
128
                } else {
129
                    reversedBinaryDataStream.append('0');
130
                }
131
            } else {
132
                reversedBinaryDataStream.append(binaryDataStream.charAt(i));
133
            }
134
        }
135
 
136
        infoLine("Binary: " + reversedBinaryDataStream);
137
 
138
        this.readable = "";
139
        this.pattern = new String[11];
140
        this.row_count = 11;
141
        this.row_height = new int[11];
142
 
143
        for (int row = 0; row < 11; row++) {
144
            final StringBuilder rowBinary = new StringBuilder(11);
145
            for (int column = 0; column < 11; column++) {
146
                if (BIT_PLACEMENT_MAP[row * 11 + column] == 1) {
147
                    rowBinary.append('1');
148
                }
149
                if (BIT_PLACEMENT_MAP[row * 11 + column] == 0) {
150
                    rowBinary.append('0');
151
                }
152
                if (BIT_PLACEMENT_MAP[row * 11 + column] >= 2) {
153
                    rowBinary.append(reversedBinaryDataStream.charAt(BIT_PLACEMENT_MAP[row * 11 + column] - 2));
154
                }
155
            }
156
            this.pattern[row] = bin2pat(rowBinary);
157
            this.row_height[row] = 1;
158
        }
159
    }
160
}