OLD | NEW |
| (Empty) |
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 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 | |
23 #include "xfa/src/fxbarcode/BC_Reader.h" | |
24 #include "xfa/src/fxbarcode/BC_Writer.h" | |
25 #include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h" | |
26 #include "xfa/src/fxbarcode/oned/BC_OneDReader.h" | |
27 #include "xfa/src/fxbarcode/oned/BC_OneDimWriter.h" | |
28 #include "xfa/src/fxbarcode/oned/BC_OnedCode39Reader.h" | |
29 #include "xfa/src/fxbarcode/oned/BC_OnedCode39Writer.h" | |
30 | |
31 CBC_OnedCode39Writer::CBC_OnedCode39Writer() { | |
32 m_extendedMode = FALSE; | |
33 m_iWideNarrRatio = 3; | |
34 } | |
35 CBC_OnedCode39Writer::CBC_OnedCode39Writer(FX_BOOL extendedMode) { | |
36 m_iWideNarrRatio = 3; | |
37 m_extendedMode = extendedMode; | |
38 } | |
39 CBC_OnedCode39Writer::~CBC_OnedCode39Writer() {} | |
40 FX_BOOL CBC_OnedCode39Writer::CheckContentValidity( | |
41 const CFX_WideStringC& contents) { | |
42 if (m_extendedMode) { | |
43 return CheckExtendedContentValidity(contents); | |
44 } | |
45 for (int32_t i = 0; i < contents.GetLength(); i++) { | |
46 FX_WCHAR ch = contents.GetAt(i); | |
47 if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || | |
48 (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z') || ch == (FX_WCHAR)'-' || | |
49 ch == (FX_WCHAR)'.' || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*' || | |
50 ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR)'+' || | |
51 ch == (FX_WCHAR)'%') { | |
52 continue; | |
53 } | |
54 return FALSE; | |
55 } | |
56 return TRUE; | |
57 } | |
58 FX_BOOL CBC_OnedCode39Writer::CheckExtendedContentValidity( | |
59 const CFX_WideStringC& contents) { | |
60 for (int32_t i = 0; i < contents.GetLength(); i++) { | |
61 FX_WCHAR ch = contents.GetAt(i); | |
62 if (ch > 127) { | |
63 return FALSE; | |
64 } | |
65 } | |
66 return TRUE; | |
67 } | |
68 CFX_WideString CBC_OnedCode39Writer::FilterContents( | |
69 const CFX_WideStringC& contents) { | |
70 if (m_extendedMode) { | |
71 return FilterExtendedContents(contents); | |
72 } | |
73 CFX_WideString filtercontents; | |
74 for (int32_t i = 0; i < contents.GetLength(); i++) { | |
75 FX_WCHAR ch = contents.GetAt(i); | |
76 if (ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1)) { | |
77 continue; | |
78 } | |
79 if (ch > 175) { | |
80 i++; | |
81 continue; | |
82 } else { | |
83 ch = Upper(ch); | |
84 } | |
85 if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || | |
86 (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z') || ch == (FX_WCHAR)'-' || | |
87 ch == (FX_WCHAR)'.' || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*' || | |
88 ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR)'+' || | |
89 ch == (FX_WCHAR)'%') { | |
90 filtercontents += ch; | |
91 } | |
92 } | |
93 return filtercontents; | |
94 } | |
95 CFX_WideString CBC_OnedCode39Writer::FilterExtendedContents( | |
96 const CFX_WideStringC& contents) { | |
97 CFX_WideString filtercontents; | |
98 for (int32_t i = 0; i < contents.GetLength(); i++) { | |
99 FX_WCHAR ch = contents.GetAt(i); | |
100 if (ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1)) { | |
101 continue; | |
102 } | |
103 if (ch > 175) { | |
104 i++; | |
105 continue; | |
106 } | |
107 if (ch > 127 && ch < 176) { | |
108 continue; | |
109 } | |
110 if (ch == 0) { | |
111 filtercontents += '%'; | |
112 filtercontents += 'U'; | |
113 } else if (ch >= 1 && ch <= 26) { | |
114 filtercontents += '$'; | |
115 filtercontents += (ch + 64); | |
116 } else if (ch >= 27 && ch <= 31) { | |
117 filtercontents += '%'; | |
118 filtercontents += (ch + 38); | |
119 } else if (ch >= 33 && ch <= 47 && ch != 45 && ch != 46) { | |
120 filtercontents += '/'; | |
121 filtercontents += (ch + 32); | |
122 } else if (ch == 58) { | |
123 filtercontents += '/'; | |
124 filtercontents += 'Z'; | |
125 } else if (ch >= 59 && ch <= 63) { | |
126 filtercontents += '%'; | |
127 filtercontents += ch + 11; | |
128 } else if (ch == 64) { | |
129 filtercontents += '%'; | |
130 filtercontents += 'V'; | |
131 } else if (ch >= 91 && ch <= 95) { | |
132 filtercontents += '%'; | |
133 filtercontents += ch - 16; | |
134 } else if (ch == 96) { | |
135 filtercontents += '%'; | |
136 filtercontents += 'W'; | |
137 } else if (ch >= 97 && ch <= 122) { | |
138 filtercontents += '+'; | |
139 filtercontents += ch - 32; | |
140 } else if (ch >= 123 && ch <= 126) { | |
141 filtercontents += '%'; | |
142 filtercontents += ch - 43; | |
143 } else if (ch == 127) { | |
144 filtercontents += '%'; | |
145 filtercontents += 'T'; | |
146 } else { | |
147 filtercontents += ch; | |
148 } | |
149 } | |
150 return filtercontents; | |
151 } | |
152 CFX_WideString CBC_OnedCode39Writer::RenderTextContents( | |
153 const CFX_WideStringC& contents) { | |
154 if (m_extendedMode) { | |
155 return RenderExtendedTextContents(contents); | |
156 } | |
157 CFX_WideString renderContents; | |
158 for (int32_t i = 0; i < contents.GetLength(); i++) { | |
159 FX_WCHAR ch = contents.GetAt(i); | |
160 if (ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1)) { | |
161 continue; | |
162 } | |
163 if (ch > 175) { | |
164 i++; | |
165 continue; | |
166 } | |
167 if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || | |
168 (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z') || | |
169 (ch >= (FX_WCHAR)'a' && ch <= (FX_WCHAR)'z') || ch == (FX_WCHAR)'-' || | |
170 ch == (FX_WCHAR)'.' || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*' || | |
171 ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR)'+' || | |
172 ch == (FX_WCHAR)'%') { | |
173 renderContents += ch; | |
174 } | |
175 } | |
176 return renderContents; | |
177 } | |
178 CFX_WideString CBC_OnedCode39Writer::RenderExtendedTextContents( | |
179 const CFX_WideStringC& contents) { | |
180 CFX_WideString renderContents; | |
181 for (int32_t i = 0; i < contents.GetLength(); i++) { | |
182 FX_WCHAR ch = contents.GetAt(i); | |
183 if (ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1)) { | |
184 continue; | |
185 } | |
186 if (ch > 175) { | |
187 i++; | |
188 continue; | |
189 } | |
190 if (ch > 127 && ch < 176) { | |
191 continue; | |
192 } | |
193 renderContents += ch; | |
194 } | |
195 return renderContents; | |
196 } | |
197 FX_BOOL CBC_OnedCode39Writer::SetTextLocation(BC_TEXT_LOC location) { | |
198 if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) { | |
199 return FALSE; | |
200 } | |
201 m_locTextLoc = location; | |
202 return TRUE; | |
203 } | |
204 FX_BOOL CBC_OnedCode39Writer::SetWideNarrowRatio(int32_t ratio) { | |
205 if (ratio < 2 || ratio > 3) { | |
206 return FALSE; | |
207 } | |
208 m_iWideNarrRatio = ratio; | |
209 return TRUE; | |
210 } | |
211 uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, | |
212 BCFORMAT format, | |
213 int32_t& outWidth, | |
214 int32_t& outHeight, | |
215 int32_t& e) { | |
216 uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); | |
217 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
218 return ret; | |
219 } | |
220 uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, | |
221 BCFORMAT format, | |
222 int32_t& outWidth, | |
223 int32_t& outHeight, | |
224 int32_t hints, | |
225 int32_t& e) { | |
226 if (format != BCFORMAT_CODE_39) { | |
227 e = BCExceptionOnlyEncodeCODE_39; | |
228 return NULL; | |
229 } | |
230 uint8_t* ret = | |
231 CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); | |
232 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
233 return ret; | |
234 } | |
235 void CBC_OnedCode39Writer::ToIntArray(int32_t a, int32_t* toReturn) { | |
236 for (int32_t i = 0; i < 9; i++) { | |
237 toReturn[i] = (a & (1 << i)) == 0 ? 1 : m_iWideNarrRatio; | |
238 } | |
239 } | |
240 FX_CHAR CBC_OnedCode39Writer::CalcCheckSum(const CFX_ByteString& contents, | |
241 int32_t& e) { | |
242 int32_t length = contents.GetLength(); | |
243 if (length > 80) { | |
244 e = BCExceptionContentsLengthShouldBetween1and80; | |
245 return '*'; | |
246 } | |
247 int32_t checksum = 0; | |
248 int32_t len = (int32_t)strlen(CBC_OnedCode39Reader::ALPHABET_STRING); | |
249 for (int32_t i = 0; i < contents.GetLength(); i++) { | |
250 int32_t j = 0; | |
251 for (; j < len; j++) { | |
252 if (CBC_OnedCode39Reader::ALPHABET_STRING[j] == contents[i]) { | |
253 if (contents[i] != '*') { | |
254 checksum += j; | |
255 break; | |
256 } else { | |
257 break; | |
258 } | |
259 } | |
260 } | |
261 if (j >= len) { | |
262 e = BCExceptionUnSupportedString; | |
263 return '*'; | |
264 } | |
265 } | |
266 checksum = checksum % 43; | |
267 return CBC_OnedCode39Reader::CHECKSUM_STRING[checksum]; | |
268 } | |
269 uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, | |
270 int32_t& outlength, | |
271 int32_t& e) { | |
272 FX_CHAR checksum = CalcCheckSum(contents, e); | |
273 if (checksum == '*') { | |
274 return NULL; | |
275 } | |
276 int32_t widths[9] = {0}; | |
277 int32_t wideStrideNum = 3; | |
278 int32_t narrStrideNum = 9 - wideStrideNum; | |
279 CFX_ByteString encodedContents = contents; | |
280 if (m_bCalcChecksum) { | |
281 encodedContents += checksum; | |
282 } | |
283 m_iContentLen = encodedContents.GetLength(); | |
284 int32_t codeWidth = (wideStrideNum * m_iWideNarrRatio + narrStrideNum) * 2 + | |
285 1 + m_iContentLen; | |
286 int32_t len = (int32_t)strlen(CBC_OnedCode39Reader::ALPHABET_STRING); | |
287 for (int32_t j = 0; j < m_iContentLen; j++) { | |
288 for (int32_t i = 0; i < len; i++) { | |
289 if (CBC_OnedCode39Reader::ALPHABET_STRING[i] == encodedContents[j]) { | |
290 ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[i], widths); | |
291 for (int32_t k = 0; k < 9; k++) { | |
292 codeWidth += widths[k]; | |
293 } | |
294 } | |
295 } | |
296 } | |
297 outlength = codeWidth; | |
298 uint8_t* result = FX_Alloc(uint8_t, codeWidth); | |
299 ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[39], widths); | |
300 int32_t pos = AppendPattern(result, 0, widths, 9, 1, e); | |
301 if (e != BCExceptionNO) { | |
302 FX_Free(result); | |
303 return NULL; | |
304 } | |
305 int32_t narrowWhite[] = {1}; | |
306 pos += AppendPattern(result, pos, narrowWhite, 1, 0, e); | |
307 if (e != BCExceptionNO) { | |
308 FX_Free(result); | |
309 return NULL; | |
310 } | |
311 for (int32_t l = m_iContentLen - 1; l >= 0; l--) { | |
312 for (int32_t i = 0; i < len; i++) { | |
313 if (CBC_OnedCode39Reader::ALPHABET_STRING[i] == encodedContents[l]) { | |
314 ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[i], widths); | |
315 pos += AppendPattern(result, pos, widths, 9, 1, e); | |
316 if (e != BCExceptionNO) { | |
317 FX_Free(result); | |
318 return NULL; | |
319 } | |
320 } | |
321 } | |
322 pos += AppendPattern(result, pos, narrowWhite, 1, 0, e); | |
323 if (e != BCExceptionNO) { | |
324 FX_Free(result); | |
325 return NULL; | |
326 } | |
327 } | |
328 ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[39], widths); | |
329 pos += AppendPattern(result, pos, widths, 9, 1, e); | |
330 if (e != BCExceptionNO) { | |
331 FX_Free(result); | |
332 return NULL; | |
333 } | |
334 for (int32_t i = 0; i < codeWidth / 2; i++) { | |
335 result[i] ^= result[codeWidth - 1 - i]; | |
336 result[codeWidth - 1 - i] ^= result[i]; | |
337 result[i] ^= result[codeWidth - 1 - i]; | |
338 } | |
339 return result; | |
340 } | |
341 CFX_WideString CBC_OnedCode39Writer::encodedContents( | |
342 const CFX_WideStringC& contents, | |
343 int32_t& e) { | |
344 CFX_WideString encodedContents = contents; | |
345 if (m_bCalcChecksum && m_bPrintChecksum) { | |
346 CFX_WideString checksumContent = FilterContents(contents); | |
347 CFX_ByteString str = checksumContent.UTF8Encode(); | |
348 FX_CHAR checksum; | |
349 checksum = CalcCheckSum(str, e); | |
350 BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); | |
351 str += checksum; | |
352 encodedContents += checksum; | |
353 } | |
354 return encodedContents; | |
355 } | |
356 void CBC_OnedCode39Writer::RenderResult(const CFX_WideStringC& contents, | |
357 uint8_t* code, | |
358 int32_t codeLength, | |
359 FX_BOOL isDevice, | |
360 int32_t& e) { | |
361 CFX_WideString encodedCon = encodedContents(contents, e); | |
362 BC_EXCEPTION_CHECK_ReturnVoid(e); | |
363 CBC_OneDimWriter::RenderResult(encodedCon, code, codeLength, isDevice, e); | |
364 } | |
OLD | NEW |