1// Copyright 2014 PDFium Authors. All rights reserved.
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 "xfa/src/fxbarcode/barcode.h"
24#include "BC_Encoder.h"
25#include "BC_DefaultPlacement.h"
26CBC_DefaultPlacement::CBC_DefaultPlacement(CFX_WideString codewords,
27                                           int32_t numcols,
28                                           int32_t numrows) {
29  m_codewords = codewords;
30  m_numcols = numcols;
31  m_numrows = numrows;
32  m_bits.SetSize(numcols * numrows);
33  for (int32_t i = 0; i < numcols * numrows; i++) {
34    m_bits[i] = (uint8_t)2;
35  }
36}
37CBC_DefaultPlacement::~CBC_DefaultPlacement() {
38  m_bits.RemoveAll();
39}
40int32_t CBC_DefaultPlacement::getNumrows() {
41  return m_numrows;
42}
43int32_t CBC_DefaultPlacement::getNumcols() {
44  return m_numcols;
45}
46CFX_ByteArray& CBC_DefaultPlacement::getBits() {
47  return m_bits;
48}
49FX_BOOL CBC_DefaultPlacement::getBit(int32_t col, int32_t row) {
50  return m_bits[row * m_numcols + col] == 1;
51}
52void CBC_DefaultPlacement::setBit(int32_t col, int32_t row, FX_BOOL bit) {
53  m_bits[row * m_numcols + col] = bit ? (uint8_t)1 : (uint8_t)0;
54}
55FX_BOOL CBC_DefaultPlacement::hasBit(int32_t col, int32_t row) {
56  return m_bits[row * m_numcols + col] != 2;
57}
58void CBC_DefaultPlacement::place() {
59  int32_t pos = 0;
60  int32_t row = 4;
61  int32_t col = 0;
62  do {
63    if ((row == m_numrows) && (col == 0)) {
64      corner1(pos++);
65    }
66    if ((row == m_numrows - 2) && (col == 0) && ((m_numcols % 4) != 0)) {
67      corner2(pos++);
68    }
69    if ((row == m_numrows - 2) && (col == 0) && (m_numcols % 8 == 4)) {
70      corner3(pos++);
71    }
72    if ((row == m_numrows + 4) && (col == 2) && ((m_numcols % 8) == 0)) {
73      corner4(pos++);
74    }
75    do {
76      if ((row < m_numrows) && (col >= 0) && !hasBit(col, row)) {
77        utah(row, col, pos++);
78      }
79      row -= 2;
80      col += 2;
81    } while (row >= 0 && (col < m_numcols));
82    row++;
83    col += 3;
84    do {
85      if ((row >= 0) && (col < m_numcols) && !hasBit(col, row)) {
86        utah(row, col, pos++);
87      }
88      row += 2;
89      col -= 2;
90    } while ((row < m_numrows) && (col >= 0));
91    row += 3;
92    col++;
93  } while ((row < m_numrows) || (col < m_numcols));
94  if (!hasBit(m_numcols - 1, m_numrows - 1)) {
95    setBit(m_numcols - 1, m_numrows - 1, TRUE);
96    setBit(m_numcols - 2, m_numrows - 2, TRUE);
97  }
98}
99void CBC_DefaultPlacement::module(int32_t row,
100                                  int32_t col,
101                                  int32_t pos,
102                                  int32_t bit) {
103  if (row < 0) {
104    row += m_numrows;
105    col += 4 - ((m_numrows + 4) % 8);
106  }
107  if (col < 0) {
108    col += m_numcols;
109    row += 4 - ((m_numcols + 4) % 8);
110  }
111  int32_t v = m_codewords.GetAt(pos);
112  v &= 1 << (8 - bit);
113  setBit(col, row, v != 0);
114}
115void CBC_DefaultPlacement::utah(int32_t row, int32_t col, int32_t pos) {
116  module(row - 2, col - 2, pos, 1);
117  module(row - 2, col - 1, pos, 2);
118  module(row - 1, col - 2, pos, 3);
119  module(row - 1, col - 1, pos, 4);
120  module(row - 1, col, pos, 5);
121  module(row, col - 2, pos, 6);
122  module(row, col - 1, pos, 7);
123  module(row, col, pos, 8);
124}
125void CBC_DefaultPlacement::corner1(int32_t pos) {
126  module(m_numrows - 1, 0, pos, 1);
127  module(m_numrows - 1, 1, pos, 2);
128  module(m_numrows - 1, 2, pos, 3);
129  module(0, m_numcols - 2, pos, 4);
130  module(0, m_numcols - 1, pos, 5);
131  module(1, m_numcols - 1, pos, 6);
132  module(2, m_numcols - 1, pos, 7);
133  module(3, m_numcols - 1, pos, 8);
134}
135void CBC_DefaultPlacement::corner2(int32_t pos) {
136  module(m_numrows - 3, 0, pos, 1);
137  module(m_numrows - 2, 0, pos, 2);
138  module(m_numrows - 1, 0, pos, 3);
139  module(0, m_numcols - 4, pos, 4);
140  module(0, m_numcols - 3, pos, 5);
141  module(0, m_numcols - 2, pos, 6);
142  module(0, m_numcols - 1, pos, 7);
143  module(1, m_numcols - 1, pos, 8);
144}
145void CBC_DefaultPlacement::corner3(int32_t pos) {
146  module(m_numrows - 3, 0, pos, 1);
147  module(m_numrows - 2, 0, pos, 2);
148  module(m_numrows - 1, 0, pos, 3);
149  module(0, m_numcols - 2, pos, 4);
150  module(0, m_numcols - 1, pos, 5);
151  module(1, m_numcols - 1, pos, 6);
152  module(2, m_numcols - 1, pos, 7);
153  module(3, m_numcols - 1, pos, 8);
154}
155void CBC_DefaultPlacement::corner4(int32_t pos) {
156  module(m_numrows - 1, 0, pos, 1);
157  module(m_numrows - 1, m_numcols - 1, pos, 2);
158  module(0, m_numcols - 3, pos, 3);
159  module(0, m_numcols - 2, pos, 4);
160  module(0, m_numcols - 1, pos, 5);
161  module(1, m_numcols - 3, pos, 6);
162  module(1, m_numcols - 2, pos, 7);
163  module(1, m_numcols - 1, pos, 8);
164}
165