1 // Copyright 2014 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 // Original code is licensed as follows:
7 /*
8 * Copyright 2006 Jeremias Maerki.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23 #include "fxbarcode/datamatrix/BC_DefaultPlacement.h"
24
25 #include <stdint.h>
26
27 #include <utility>
28
29 #include "core/fxcrt/data_vector.h"
30 #include "core/fxcrt/fx_2d_size.h"
31 #include "fxbarcode/datamatrix/BC_Encoder.h"
32 #include "third_party/base/check_op.h"
33
34 namespace {
35
GetIndex(size_t col,size_t row,size_t num_cols)36 size_t GetIndex(size_t col, size_t row, size_t num_cols) {
37 return row * num_cols + col;
38 }
39
40 } // namespace
41
CBC_DefaultPlacement(WideString codewords,int32_t numcols,int32_t numrows)42 CBC_DefaultPlacement::CBC_DefaultPlacement(WideString codewords,
43 int32_t numcols,
44 int32_t numrows)
45 : m_codewords(std::move(codewords)),
46 m_numrows(numrows),
47 m_numcols(numcols),
48 m_bits(Fx2DSizeOrDie(numcols, numrows), 2) {
49 CHECK_GT(m_numrows, 0);
50 CHECK_GT(m_numcols, 0);
51 Init();
52 }
53
54 CBC_DefaultPlacement::~CBC_DefaultPlacement() = default;
55
GetBit(int32_t col,int32_t row) const56 bool CBC_DefaultPlacement::GetBit(int32_t col, int32_t row) const {
57 CHECK_GE(col, 0);
58 CHECK_GE(row, 0);
59 CHECK_LT(col, m_numcols);
60 CHECK_LT(row, m_numrows);
61 return m_bits[GetIndex(col, row, m_numcols)] == 1;
62 }
63
SetBit(int32_t col,int32_t row,bool bit)64 void CBC_DefaultPlacement::SetBit(int32_t col, int32_t row, bool bit) {
65 DCHECK_GE(col, 0);
66 DCHECK_GE(row, 0);
67 DCHECK_LT(col, m_numcols);
68 DCHECK_LT(row, m_numrows);
69 m_bits[GetIndex(col, row, m_numcols)] = bit ? 1 : 0;
70 }
71
HasBit(int32_t col,int32_t row) const72 bool CBC_DefaultPlacement::HasBit(int32_t col, int32_t row) const {
73 DCHECK_GE(col, 0);
74 DCHECK_GE(row, 0);
75 DCHECK_LT(col, m_numcols);
76 DCHECK_LT(row, m_numrows);
77 return m_bits[GetIndex(col, row, m_numcols)] != 2;
78 }
79
Init()80 void CBC_DefaultPlacement::Init() {
81 int32_t pos = 0;
82 int32_t row = 4;
83 int32_t col = 0;
84 do {
85 if ((row == m_numrows) && (col == 0)) {
86 SetCorner1(pos++);
87 }
88 if ((row == m_numrows - 2) && (col == 0) && ((m_numcols % 4) != 0)) {
89 SetCorner2(pos++);
90 }
91 if ((row == m_numrows - 2) && (col == 0) && (m_numcols % 8 == 4)) {
92 SetCorner3(pos++);
93 }
94 if ((row == m_numrows + 4) && (col == 2) && ((m_numcols % 8) == 0)) {
95 SetCorner4(pos++);
96 }
97 do {
98 if ((row < m_numrows) && (col >= 0) && !HasBit(col, row)) {
99 SetUtah(row, col, pos++);
100 }
101 row -= 2;
102 col += 2;
103 } while (row >= 0 && (col < m_numcols));
104 row++;
105 col += 3;
106 do {
107 if ((row >= 0) && (col < m_numcols) && !HasBit(col, row)) {
108 SetUtah(row, col, pos++);
109 }
110 row += 2;
111 col -= 2;
112 } while ((row < m_numrows) && (col >= 0));
113 row += 3;
114 col++;
115 } while ((row < m_numrows) || (col < m_numcols));
116 if (!HasBit(m_numcols - 1, m_numrows - 1)) {
117 SetBit(m_numcols - 1, m_numrows - 1, true);
118 SetBit(m_numcols - 2, m_numrows - 2, true);
119 }
120 }
121
SetModule(int32_t row,int32_t col,int32_t pos,int32_t bit)122 void CBC_DefaultPlacement::SetModule(int32_t row,
123 int32_t col,
124 int32_t pos,
125 int32_t bit) {
126 if (row < 0) {
127 row += m_numrows;
128 col += 4 - ((m_numrows + 4) % 8);
129 }
130 if (col < 0) {
131 col += m_numcols;
132 row += 4 - ((m_numcols + 4) % 8);
133 }
134 int32_t v = m_codewords[pos];
135 v &= 1 << (8 - bit);
136 SetBit(col, row, v != 0);
137 }
138
SetUtah(int32_t row,int32_t col,int32_t pos)139 void CBC_DefaultPlacement::SetUtah(int32_t row, int32_t col, int32_t pos) {
140 SetModule(row - 2, col - 2, pos, 1);
141 SetModule(row - 2, col - 1, pos, 2);
142 SetModule(row - 1, col - 2, pos, 3);
143 SetModule(row - 1, col - 1, pos, 4);
144 SetModule(row - 1, col, pos, 5);
145 SetModule(row, col - 2, pos, 6);
146 SetModule(row, col - 1, pos, 7);
147 SetModule(row, col, pos, 8);
148 }
149
SetCorner1(int32_t pos)150 void CBC_DefaultPlacement::SetCorner1(int32_t pos) {
151 SetModule(m_numrows - 1, 0, pos, 1);
152 SetModule(m_numrows - 1, 1, pos, 2);
153 SetModule(m_numrows - 1, 2, pos, 3);
154 SetModule(0, m_numcols - 2, pos, 4);
155 SetModule(0, m_numcols - 1, pos, 5);
156 SetModule(1, m_numcols - 1, pos, 6);
157 SetModule(2, m_numcols - 1, pos, 7);
158 SetModule(3, m_numcols - 1, pos, 8);
159 }
160
SetCorner2(int32_t pos)161 void CBC_DefaultPlacement::SetCorner2(int32_t pos) {
162 SetModule(m_numrows - 3, 0, pos, 1);
163 SetModule(m_numrows - 2, 0, pos, 2);
164 SetModule(m_numrows - 1, 0, pos, 3);
165 SetModule(0, m_numcols - 4, pos, 4);
166 SetModule(0, m_numcols - 3, pos, 5);
167 SetModule(0, m_numcols - 2, pos, 6);
168 SetModule(0, m_numcols - 1, pos, 7);
169 SetModule(1, m_numcols - 1, pos, 8);
170 }
171
SetCorner3(int32_t pos)172 void CBC_DefaultPlacement::SetCorner3(int32_t pos) {
173 SetModule(m_numrows - 3, 0, pos, 1);
174 SetModule(m_numrows - 2, 0, pos, 2);
175 SetModule(m_numrows - 1, 0, pos, 3);
176 SetModule(0, m_numcols - 2, pos, 4);
177 SetModule(0, m_numcols - 1, pos, 5);
178 SetModule(1, m_numcols - 1, pos, 6);
179 SetModule(2, m_numcols - 1, pos, 7);
180 SetModule(3, m_numcols - 1, pos, 8);
181 }
182
SetCorner4(int32_t pos)183 void CBC_DefaultPlacement::SetCorner4(int32_t pos) {
184 SetModule(m_numrows - 1, 0, pos, 1);
185 SetModule(m_numrows - 1, m_numcols - 1, pos, 2);
186 SetModule(0, m_numcols - 3, pos, 3);
187 SetModule(0, m_numcols - 2, pos, 4);
188 SetModule(0, m_numcols - 1, pos, 5);
189 SetModule(1, m_numcols - 3, pos, 6);
190 SetModule(1, m_numcols - 2, pos, 7);
191 SetModule(1, m_numcols - 1, pos, 8);
192 }
193