2 * Copyright (c) 2018-2019. Developed by Hedgecode.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.hedgecode.chess.qrcode;
19 import com.google.zxing.common.BitMatrix;
20 import com.google.zxing.qrcode.encoder.ByteMatrix;
23 * Chess-specific QR Codes binary matrix accessory utils.
25 * @author Dmitry Samoshin aka gotty
27 public final class ChessQRMatrixUtils {
30 private static final int[][] CHESS_LOGO_PATTERN = {
31 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
32 {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
33 {0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0},
34 {0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1},
35 {0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1},
36 {0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1},
37 {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
38 {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
39 {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
40 {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
41 {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
42 {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
47 private static final int[][] CHESS_LOGO_PATTERN = {
48 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
49 {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},
50 {0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1},
51 {0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1},
52 {0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1},
53 {0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1},
54 {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1},
55 {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1},
56 {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1},
57 {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1},
58 {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
59 {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
60 {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
64 private static final int[][] CHESS_LOGO_PATTERN = {
65 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
66 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
67 {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1},
68 {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1},
69 {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1},
70 {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1},
71 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1},
72 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1},
73 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1},
74 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1},
75 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
76 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
80 private static final int CHESS_LOGO_PATTERN_LENGTH = CHESS_LOGO_PATTERN[0].length;
83 static ByteMatrix embedChessLogoPattern(ByteMatrix byteMatrix) {
84 if (byteMatrix == null || byteMatrix.getWidth() < CHESS_LOGO_PATTERN_LENGTH + 14)
85 return null; // todo: check for Version
87 int xStart = (byteMatrix.getWidth() - CHESS_LOGO_PATTERN_LENGTH) / 2;
88 int yStart = (byteMatrix.getHeight() - CHESS_LOGO_PATTERN_LENGTH) / 2;
90 for (int y = 0; y < CHESS_LOGO_PATTERN_LENGTH; ++y) {
91 int[] patternY = CHESS_LOGO_PATTERN[y];
92 for (int x = 0; x < CHESS_LOGO_PATTERN_LENGTH; ++x) {
93 byteMatrix.set(xStart + x, yStart + y, patternY[x]);
100 static boolean checkChessLogoPattern(ByteMatrix byteMatrix) {
106 static boolean checkChessLogoPattern(BitMatrix bitMatrix) {
113 static BitMatrix renderMatrix(ByteMatrix byteMatrix, int width, int height, int quietZone) {
114 int inputWidth = byteMatrix.getWidth();
115 int inputHeight = byteMatrix.getHeight();
116 int qrWidth = inputWidth + (quietZone * 2);
117 int qrHeight = inputHeight + (quietZone * 2);
118 int outputWidth = Math.max(width, qrWidth);
119 int outputHeight = Math.max(height, qrHeight);
121 int multiple = Math.min(outputWidth / qrWidth, outputHeight / qrHeight);
122 int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
123 int topPadding = (outputHeight - (inputHeight * multiple)) / 2;
125 BitMatrix bitMatrix = new BitMatrix(outputWidth, outputHeight);
127 for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
128 for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
129 if (byteMatrix.get(inputX, inputY) == 1) {
130 bitMatrix.setRegion(outputX, outputY, multiple, multiple);