blob: ed2d2c1b2494242503b0d44dbd01134ec4d8bd2e [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// 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 2010 ZXing authors
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
Dan Sinclair1770c022016-03-14 14:14:16 -040023#include "xfa/fxbarcode/BC_Writer.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040024#include "xfa/fxbarcode/oned/BC_OneDimWriter.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040025#include "xfa/fxbarcode/oned/BC_OnedCode128Writer.h"
26
dsinclaira2615342016-06-16 12:29:07 -070027namespace {
28
29const int32_t CODE_PATTERNS[107][7] = {
30 {2, 1, 2, 2, 2, 2, 0}, {2, 2, 2, 1, 2, 2, 0}, {2, 2, 2, 2, 2, 1, 0},
31 {1, 2, 1, 2, 2, 3, 0}, {1, 2, 1, 3, 2, 2, 0}, {1, 3, 1, 2, 2, 2, 0},
32 {1, 2, 2, 2, 1, 3, 0}, {1, 2, 2, 3, 1, 2, 0}, {1, 3, 2, 2, 1, 2, 0},
33 {2, 2, 1, 2, 1, 3, 0}, {2, 2, 1, 3, 1, 2, 0}, {2, 3, 1, 2, 1, 2, 0},
34 {1, 1, 2, 2, 3, 2, 0}, {1, 2, 2, 1, 3, 2, 0}, {1, 2, 2, 2, 3, 1, 0},
35 {1, 1, 3, 2, 2, 2, 0}, {1, 2, 3, 1, 2, 2, 0}, {1, 2, 3, 2, 2, 1, 0},
36 {2, 2, 3, 2, 1, 1, 0}, {2, 2, 1, 1, 3, 2, 0}, {2, 2, 1, 2, 3, 1, 0},
37 {2, 1, 3, 2, 1, 2, 0}, {2, 2, 3, 1, 1, 2, 0}, {3, 1, 2, 1, 3, 1, 0},
38 {3, 1, 1, 2, 2, 2, 0}, {3, 2, 1, 1, 2, 2, 0}, {3, 2, 1, 2, 2, 1, 0},
39 {3, 1, 2, 2, 1, 2, 0}, {3, 2, 2, 1, 1, 2, 0}, {3, 2, 2, 2, 1, 1, 0},
40 {2, 1, 2, 1, 2, 3, 0}, {2, 1, 2, 3, 2, 1, 0}, {2, 3, 2, 1, 2, 1, 0},
41 {1, 1, 1, 3, 2, 3, 0}, {1, 3, 1, 1, 2, 3, 0}, {1, 3, 1, 3, 2, 1, 0},
42 {1, 1, 2, 3, 1, 3, 0}, {1, 3, 2, 1, 1, 3, 0}, {1, 3, 2, 3, 1, 1, 0},
43 {2, 1, 1, 3, 1, 3, 0}, {2, 3, 1, 1, 1, 3, 0}, {2, 3, 1, 3, 1, 1, 0},
44 {1, 1, 2, 1, 3, 3, 0}, {1, 1, 2, 3, 3, 1, 0}, {1, 3, 2, 1, 3, 1, 0},
45 {1, 1, 3, 1, 2, 3, 0}, {1, 1, 3, 3, 2, 1, 0}, {1, 3, 3, 1, 2, 1, 0},
46 {3, 1, 3, 1, 2, 1, 0}, {2, 1, 1, 3, 3, 1, 0}, {2, 3, 1, 1, 3, 1, 0},
47 {2, 1, 3, 1, 1, 3, 0}, {2, 1, 3, 3, 1, 1, 0}, {2, 1, 3, 1, 3, 1, 0},
48 {3, 1, 1, 1, 2, 3, 0}, {3, 1, 1, 3, 2, 1, 0}, {3, 3, 1, 1, 2, 1, 0},
49 {3, 1, 2, 1, 1, 3, 0}, {3, 1, 2, 3, 1, 1, 0}, {3, 3, 2, 1, 1, 1, 0},
50 {3, 1, 4, 1, 1, 1, 0}, {2, 2, 1, 4, 1, 1, 0}, {4, 3, 1, 1, 1, 1, 0},
51 {1, 1, 1, 2, 2, 4, 0}, {1, 1, 1, 4, 2, 2, 0}, {1, 2, 1, 1, 2, 4, 0},
52 {1, 2, 1, 4, 2, 1, 0}, {1, 4, 1, 1, 2, 2, 0}, {1, 4, 1, 2, 2, 1, 0},
53 {1, 1, 2, 2, 1, 4, 0}, {1, 1, 2, 4, 1, 2, 0}, {1, 2, 2, 1, 1, 4, 0},
54 {1, 2, 2, 4, 1, 1, 0}, {1, 4, 2, 1, 1, 2, 0}, {1, 4, 2, 2, 1, 1, 0},
55 {2, 4, 1, 2, 1, 1, 0}, {2, 2, 1, 1, 1, 4, 0}, {4, 1, 3, 1, 1, 1, 0},
56 {2, 4, 1, 1, 1, 2, 0}, {1, 3, 4, 1, 1, 1, 0}, {1, 1, 1, 2, 4, 2, 0},
57 {1, 2, 1, 1, 4, 2, 0}, {1, 2, 1, 2, 4, 1, 0}, {1, 1, 4, 2, 1, 2, 0},
58 {1, 2, 4, 1, 1, 2, 0}, {1, 2, 4, 2, 1, 1, 0}, {4, 1, 1, 2, 1, 2, 0},
59 {4, 2, 1, 1, 1, 2, 0}, {4, 2, 1, 2, 1, 1, 0}, {2, 1, 2, 1, 4, 1, 0},
60 {2, 1, 4, 1, 2, 1, 0}, {4, 1, 2, 1, 2, 1, 0}, {1, 1, 1, 1, 4, 3, 0},
61 {1, 1, 1, 3, 4, 1, 0}, {1, 3, 1, 1, 4, 1, 0}, {1, 1, 4, 1, 1, 3, 0},
62 {1, 1, 4, 3, 1, 1, 0}, {4, 1, 1, 1, 1, 3, 0}, {4, 1, 1, 3, 1, 1, 0},
63 {1, 1, 3, 1, 4, 1, 0}, {1, 1, 4, 1, 3, 1, 0}, {3, 1, 1, 1, 4, 1, 0},
64 {4, 1, 1, 1, 3, 1, 0}, {2, 1, 1, 4, 1, 2, 0}, {2, 1, 1, 2, 1, 4, 0},
65 {2, 1, 1, 2, 3, 2, 0}, {2, 3, 3, 1, 1, 1, 2}};
66
67const int32_t CODE_START_B = 104;
68const int32_t CODE_START_C = 105;
69const int32_t CODE_STOP = 106;
70
71} // namespace
72
Dan Sinclair1770c022016-03-14 14:14:16 -040073CBC_OnedCode128Writer::CBC_OnedCode128Writer() {
74 m_codeFormat = BC_CODE128_B;
75}
76CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type) {
77 m_codeFormat = type;
78}
79CBC_OnedCode128Writer::~CBC_OnedCode128Writer() {}
80BC_TYPE CBC_OnedCode128Writer::GetType() {
81 return m_codeFormat;
82}
tsepezd19e9122016-11-02 15:43:18 -070083bool CBC_OnedCode128Writer::CheckContentValidity(
Dan Sinclair1770c022016-03-14 14:14:16 -040084 const CFX_WideStringC& contents) {
tsepezd19e9122016-11-02 15:43:18 -070085 bool ret = true;
Dan Sinclair1770c022016-03-14 14:14:16 -040086 int32_t position = 0;
87 int32_t patternIndex = -1;
88 if (m_codeFormat == BC_CODE128_B || m_codeFormat == BC_CODE128_C) {
89 while (position < contents.GetLength()) {
90 patternIndex = (int32_t)contents.GetAt(position);
weili038aa532016-05-20 15:38:29 -070091 if (patternIndex < 32 || patternIndex > 126 || patternIndex == 34) {
tsepezd19e9122016-11-02 15:43:18 -070092 ret = false;
Dan Sinclair1770c022016-03-14 14:14:16 -040093 break;
94 }
95 position++;
96 }
97 } else {
tsepezd19e9122016-11-02 15:43:18 -070098 ret = false;
Dan Sinclair1770c022016-03-14 14:14:16 -040099 }
100 return ret;
101}
102CFX_WideString CBC_OnedCode128Writer::FilterContents(
103 const CFX_WideStringC& contents) {
104 CFX_WideString filterChineseChar;
105 FX_WCHAR ch;
106 for (int32_t i = 0; i < contents.GetLength(); i++) {
107 ch = contents.GetAt(i);
108 if (ch > 175) {
109 i++;
110 continue;
111 }
112 filterChineseChar += ch;
113 }
114 CFX_WideString filtercontents;
115 if (m_codeFormat == BC_CODE128_B) {
116 for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) {
117 ch = filterChineseChar.GetAt(i);
118 if (ch >= 32 && ch <= 126) {
119 filtercontents += ch;
120 } else {
121 continue;
122 }
123 }
124 } else if (m_codeFormat == BC_CODE128_C) {
125 for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) {
126 ch = filterChineseChar.GetAt(i);
127 if (ch >= 32 && ch <= 106) {
128 filtercontents += ch;
129 } else {
130 continue;
131 }
132 }
133 } else {
134 filtercontents = contents;
135 }
136 return filtercontents;
137}
tsepezd19e9122016-11-02 15:43:18 -0700138bool CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400139 if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {
tsepezd19e9122016-11-02 15:43:18 -0700140 return false;
Dan Sinclair1770c022016-03-14 14:14:16 -0400141 }
142 m_locTextLoc = location;
tsepezd19e9122016-11-02 15:43:18 -0700143 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400144}
145uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
146 BCFORMAT format,
147 int32_t& outWidth,
148 int32_t& outHeight,
149 int32_t hints,
150 int32_t& e) {
151 if (format != BCFORMAT_CODE_128) {
152 e = BCExceptionOnlyEncodeCODE_128;
thestig6dc1d772016-06-09 18:39:33 -0700153 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400154 }
155 uint8_t* ret =
156 CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
thestig6dc1d772016-06-09 18:39:33 -0700157 BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
Dan Sinclair1770c022016-03-14 14:14:16 -0400158 return ret;
159}
160uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
161 BCFORMAT format,
162 int32_t& outWidth,
163 int32_t& outHeight,
164 int32_t& e) {
165 uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e);
thestig6dc1d772016-06-09 18:39:33 -0700166 BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
Dan Sinclair1770c022016-03-14 14:14:16 -0400167 return ret;
168}
tsepezd19e9122016-11-02 15:43:18 -0700169bool CBC_OnedCode128Writer::IsDigits(const CFX_ByteString& contents,
170 int32_t start,
171 int32_t length) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400172 int32_t end = start + length;
173 for (int32_t i = start; i < end; i++) {
174 if (contents[i] < '0' || contents[i] > '9') {
tsepezd19e9122016-11-02 15:43:18 -0700175 return false;
Dan Sinclair1770c022016-03-14 14:14:16 -0400176 }
177 }
tsepezd19e9122016-11-02 15:43:18 -0700178 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400179}
tsepeze801d4e2016-04-29 13:45:14 -0700180
Dan Sinclair1770c022016-03-14 14:14:16 -0400181uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
182 int32_t& outLength,
183 int32_t& e) {
184 if (contents.GetLength() < 1 || contents.GetLength() > 80) {
185 e = BCExceptionContentsLengthShouldBetween1and80;
tsepeze801d4e2016-04-29 13:45:14 -0700186 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400187 }
tsepeze801d4e2016-04-29 13:45:14 -0700188 CFX_ArrayTemplate<const int32_t*> patterns;
Dan Sinclair1770c022016-03-14 14:14:16 -0400189 int32_t checkSum = 0;
190 if (m_codeFormat == BC_CODE128_B) {
tsepeze801d4e2016-04-29 13:45:14 -0700191 checkSum = Encode128B(contents, &patterns);
Dan Sinclair1770c022016-03-14 14:14:16 -0400192 } else if (m_codeFormat == BC_CODE128_C) {
tsepeze801d4e2016-04-29 13:45:14 -0700193 checkSum = Encode128C(contents, &patterns);
Dan Sinclair1770c022016-03-14 14:14:16 -0400194 } else {
195 e = BCExceptionFormatException;
tsepeze801d4e2016-04-29 13:45:14 -0700196 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400197 }
198 checkSum %= 103;
dsinclaira2615342016-06-16 12:29:07 -0700199 patterns.Add(CODE_PATTERNS[checkSum]);
200 patterns.Add(CODE_PATTERNS[CODE_STOP]);
Dan Sinclair1770c022016-03-14 14:14:16 -0400201 m_iContentLen = contents.GetLength() + 3;
202 int32_t codeWidth = 0;
203 for (int32_t k = 0; k < patterns.GetSize(); k++) {
tsepeze801d4e2016-04-29 13:45:14 -0700204 const int32_t* pattern = patterns[k];
Dan Sinclair1770c022016-03-14 14:14:16 -0400205 for (int32_t j = 0; j < 7; j++) {
206 codeWidth += pattern[j];
207 }
208 }
209 outLength = codeWidth;
210 uint8_t* result = FX_Alloc(uint8_t, outLength);
211 int32_t pos = 0;
212 for (int32_t j = 0; j < patterns.GetSize(); j++) {
tsepeze801d4e2016-04-29 13:45:14 -0700213 const int32_t* pattern = patterns[j];
Dan Sinclair1770c022016-03-14 14:14:16 -0400214 pos += AppendPattern(result, pos, pattern, 7, 1, e);
215 if (e != BCExceptionNO) {
216 FX_Free(result);
tsepeze801d4e2016-04-29 13:45:14 -0700217 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400218 }
219 }
220 return result;
221}
tsepeze801d4e2016-04-29 13:45:14 -0700222
223int32_t CBC_OnedCode128Writer::Encode128B(
224 const CFX_ByteString& contents,
225 CFX_ArrayTemplate<const int32_t*>* patterns) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400226 int32_t checkSum = 0;
227 int32_t checkWeight = 1;
228 int32_t position = 0;
dsinclaira2615342016-06-16 12:29:07 -0700229 patterns->Add(CODE_PATTERNS[CODE_START_B]);
Dan Sinclair1770c022016-03-14 14:14:16 -0400230 checkSum += CODE_START_B * checkWeight;
231 while (position < contents.GetLength()) {
232 int32_t patternIndex = 0;
233 patternIndex = contents[position] - ' ';
234 position += 1;
dsinclaira2615342016-06-16 12:29:07 -0700235 patterns->Add(CODE_PATTERNS[patternIndex]);
Dan Sinclair1770c022016-03-14 14:14:16 -0400236 checkSum += patternIndex * checkWeight;
237 if (position != 0) {
238 checkWeight++;
239 }
240 }
241 return checkSum;
242}
tsepeze801d4e2016-04-29 13:45:14 -0700243
244int32_t CBC_OnedCode128Writer::Encode128C(
245 const CFX_ByteString& contents,
246 CFX_ArrayTemplate<const int32_t*>* patterns) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400247 int32_t checkSum = 0;
248 int32_t checkWeight = 1;
249 int32_t position = 0;
dsinclaira2615342016-06-16 12:29:07 -0700250 patterns->Add(CODE_PATTERNS[CODE_START_C]);
Dan Sinclair1770c022016-03-14 14:14:16 -0400251 checkSum += CODE_START_C * checkWeight;
252 while (position < contents.GetLength()) {
253 int32_t patternIndex = 0;
254 FX_CHAR ch = contents.GetAt(position);
255 if (ch < '0' || ch > '9') {
256 patternIndex = (int32_t)ch;
257 position++;
258 } else {
tsepezb4c9f3f2016-04-13 15:41:21 -0700259 patternIndex = FXSYS_atoi(contents.Mid(position, 2).c_str());
Dan Sinclair1770c022016-03-14 14:14:16 -0400260 if (contents.GetAt(position + 1) < '0' ||
261 contents.GetAt(position + 1) > '9') {
262 position += 1;
263 } else {
264 position += 2;
265 }
266 }
dsinclaira2615342016-06-16 12:29:07 -0700267 patterns->Add(CODE_PATTERNS[patternIndex]);
Dan Sinclair1770c022016-03-14 14:14:16 -0400268 checkSum += patternIndex * checkWeight;
269 if (position != 0) {
270 checkWeight++;
271 }
272 }
273 return checkSum;
274}