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 "barcode.h" | |
24 #include "include/BC_Writer.h" | |
25 #include "include/BC_Reader.h" | |
26 #include "include/BC_OneDReader.h" | |
27 #include "include/BC_OneDimWriter.h" | |
28 #include "include/BC_OnedCode39Reader.h" | |
29 #include "include/BC_OnedCode39Writer.h" | |
30 #include "include/BC_CommonBitMatrix.h" | |
31 CBC_OnedCode39Writer::CBC_OnedCode39Writer() | |
32 { | |
33 m_extendedMode = FALSE; | |
34 m_iWideNarrRatio = 3; | |
35 } | |
36 CBC_OnedCode39Writer::CBC_OnedCode39Writer(FX_BOOL extendedMode) | |
37 { | |
38 m_iWideNarrRatio = 3; | |
39 m_extendedMode = extendedMode; | |
40 } | |
41 CBC_OnedCode39Writer::~CBC_OnedCode39Writer() | |
42 { | |
43 } | |
44 FX_BOOL CBC_OnedCode39Writer::CheckContentValidity(FX_WSTR contents) | |
45 { | |
46 if (m_extendedMode) { | |
47 return CheckExtendedContentValidity(contents); | |
48 } | |
49 for(FX_INT32 i = 0; i < contents.GetLength(); i++) { | |
50 FX_WCHAR ch = contents.GetAt(i); | |
51 if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || (ch >= (FX_WCHAR)'A'
&& ch <= (FX_WCHAR)'Z') | |
52 || ch == (FX_WCHAR)'-' || ch == (FX_WCHAR)'.' || ch == (FX_WCHAR
)' ' || ch == (FX_WCHAR)'*' | |
53 || ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR
)'+' || ch == (FX_WCHAR)'%') { | |
54 continue; | |
55 } | |
56 return FALSE; | |
57 } | |
58 return TRUE; | |
59 } | |
60 FX_BOOL CBC_OnedCode39Writer::CheckExtendedContentValidity(FX_WSTR contents) | |
61 { | |
62 for(FX_INT32 i = 0; i < contents.GetLength(); i++) { | |
63 FX_WCHAR ch = contents.GetAt(i); | |
64 if (ch > 127) { | |
65 return FALSE; | |
66 } | |
67 } | |
68 return TRUE; | |
69 } | |
70 CFX_WideString CBC_OnedCode39Writer::FilterContents(FX_WSTR contents) | |
71 { | |
72 if (m_extendedMode) { | |
73 return FilterExtendedContents(contents); | |
74 } | |
75 CFX_WideString filtercontents; | |
76 for(FX_INT32 i = 0; i < contents.GetLength(); i++) { | |
77 FX_WCHAR ch = contents.GetAt(i); | |
78 if ( ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1) )
{ | |
79 continue; | |
80 } | |
81 if(ch > 175) { | |
82 i++; | |
83 continue; | |
84 } else { | |
85 ch = Upper(ch); | |
86 } | |
87 if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || (ch >= (FX_WCHAR)'A'
&& ch <= (FX_WCHAR)'Z') | |
88 || ch == (FX_WCHAR)'-' || ch == (FX_WCHAR)'.' || ch == (FX_WCHAR
)' ' || ch == (FX_WCHAR)'*' | |
89 || ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR
)'+' || ch == (FX_WCHAR)'%') { | |
90 filtercontents += ch; | |
91 } | |
92 } | |
93 return filtercontents; | |
94 } | |
95 CFX_WideString CBC_OnedCode39Writer::FilterExtendedContents(FX_WSTR contents) | |
96 { | |
97 CFX_WideString filtercontents; | |
98 for(FX_INT32 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(FX_WSTR contents) | |
153 { | |
154 if (m_extendedMode) { | |
155 return RenderExtendedTextContents(contents); | |
156 } | |
157 CFX_WideString renderContents; | |
158 for(FX_INT32 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') || (ch >= (FX_WCHAR)'A'
&& ch <= (FX_WCHAR)'Z') | |
168 || (ch >= (FX_WCHAR)'a' && ch <= (FX_WCHAR)'z') || ch == (FX_WCH
AR)'-' || ch == (FX_WCHAR)'.' | |
169 || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*' || ch == (FX_WCHAR
)'$' || ch == (FX_WCHAR)'/' | |
170 || ch == (FX_WCHAR)'+' || ch == (FX_WCHAR)'%') { | |
171 renderContents += ch; | |
172 } | |
173 } | |
174 return renderContents; | |
175 } | |
176 CFX_WideString CBC_OnedCode39Writer::RenderExtendedTextContents(FX_WSTR contents
) | |
177 { | |
178 CFX_WideString renderContents; | |
179 for(FX_INT32 i = 0; i < contents.GetLength(); i++) { | |
180 FX_WCHAR ch = contents.GetAt(i); | |
181 if ( ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1) )
{ | |
182 continue; | |
183 } | |
184 if(ch > 175) { | |
185 i++; | |
186 continue; | |
187 } | |
188 if (ch > 127 && ch < 176) { | |
189 continue; | |
190 } | |
191 renderContents += ch; | |
192 } | |
193 return renderContents; | |
194 } | |
195 FX_BOOL CBC_OnedCode39Writer::SetTextLocation(BC_TEXT_LOC location) | |
196 { | |
197 if ( location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) { | |
198 return FALSE; | |
199 } | |
200 m_locTextLoc = location; | |
201 return TRUE; | |
202 } | |
203 FX_BOOL CBC_OnedCode39Writer::SetWideNarrowRatio(FX_INT32 ratio) | |
204 { | |
205 if ( ratio < 2 || ratio > 3) { | |
206 return FALSE; | |
207 } | |
208 m_iWideNarrRatio = ratio; | |
209 return TRUE; | |
210 } | |
211 FX_BYTE *CBC_OnedCode39Writer::Encode(const CFX_ByteString &contents, BCFORMAT f
ormat, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e) | |
212 { | |
213 FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0 , e); | |
214 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
215 return ret; | |
216 } | |
217 FX_BYTE *CBC_OnedCode39Writer::Encode(const CFX_ByteString &contents, BCFORMAT f
ormat, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e) | |
218 { | |
219 if(format != BCFORMAT_CODE_39) { | |
220 e = BCExceptionOnlyEncodeCODE_39; | |
221 return NULL; | |
222 } | |
223 FX_BYTE *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeigh
t, hints, e); | |
224 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
225 return ret; | |
226 } | |
227 void CBC_OnedCode39Writer::ToIntArray(FX_INT32 a, FX_INT32 *toReturn) | |
228 { | |
229 for(FX_INT32 i = 0; i < 9; i++) { | |
230 toReturn[i] = (a & (1 << i) ) == 0 ? 1 : m_iWideNarrRatio; | |
231 } | |
232 } | |
233 FX_CHAR CBC_OnedCode39Writer::CalcCheckSum(const CFX_ByteString &contents, FX_IN
T32 &e) | |
234 { | |
235 FX_INT32 length = contents.GetLength(); | |
236 if (length > 80) { | |
237 e = BCExceptionContentsLengthShouldBetween1and80; | |
238 return '*'; | |
239 } | |
240 FX_INT32 checksum = 0; | |
241 FX_INT32 len = (FX_INT32)strlen(CBC_OnedCode39Reader::ALPHABET_STRING); | |
242 for(FX_INT32 i = 0; i < contents.GetLength(); i++) { | |
243 FX_INT32 j = 0; | |
244 for (; j < len; j++) { | |
245 if (CBC_OnedCode39Reader::ALPHABET_STRING[j] == contents[i]) { | |
246 if(contents[i] != '*') { | |
247 checksum += j; | |
248 break; | |
249 } else { | |
250 break; | |
251 } | |
252 } | |
253 } | |
254 if (j >= len) { | |
255 e = BCExceptionUnSupportedString; | |
256 return '*'; | |
257 } | |
258 } | |
259 checksum = checksum % 43; | |
260 return CBC_OnedCode39Reader::CHECKSUM_STRING[checksum]; | |
261 } | |
262 FX_BYTE *CBC_OnedCode39Writer::Encode(const CFX_ByteString &contents, FX_INT32 &
outlength , FX_INT32 &e) | |
263 { | |
264 FX_CHAR checksum = CalcCheckSum(contents, e); | |
265 if (checksum == '*') { | |
266 return NULL; | |
267 } | |
268 FX_INT32 widths[9] = {0}; | |
269 FX_INT32 wideStrideNum = 3; | |
270 FX_INT32 narrStrideNum = 9 - wideStrideNum; | |
271 CFX_ByteString encodedContents = contents; | |
272 if ( m_bCalcChecksum ) { | |
273 encodedContents += checksum; | |
274 } | |
275 m_iContentLen = encodedContents.GetLength(); | |
276 FX_INT32 codeWidth = (wideStrideNum * m_iWideNarrRatio + narrStrideNum) * 2
+ 1 + m_iContentLen; | |
277 FX_INT32 len = (FX_INT32)strlen(CBC_OnedCode39Reader::ALPHABET_STRING); | |
278 for (FX_INT32 j = 0; j < m_iContentLen; j++) { | |
279 for (FX_INT32 i = 0; i < len; i++) { | |
280 if (CBC_OnedCode39Reader::ALPHABET_STRING[i] == encodedContents[j])
{ | |
281 ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[i], widths)
; | |
282 for(FX_INT32 k = 0; k < 9; k++) { | |
283 codeWidth += widths[k]; | |
284 } | |
285 } | |
286 } | |
287 } | |
288 outlength = codeWidth; | |
289 FX_BYTE *result = FX_Alloc(FX_BYTE, codeWidth); | |
290 ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[39], widths); | |
291 FX_INT32 pos = AppendPattern(result, 0, widths, 9, 1 , e); | |
292 if (e != BCExceptionNO) { | |
293 FX_Free (result); | |
294 return NULL; | |
295 } | |
296 FX_INT32 narrowWhite[] = {1}; | |
297 pos += AppendPattern(result, pos, narrowWhite, 1, 0, e); | |
298 if (e != BCExceptionNO) { | |
299 FX_Free (result); | |
300 return NULL; | |
301 } | |
302 for(FX_INT32 l = m_iContentLen - 1; l >= 0; l--) { | |
303 for (FX_INT32 i = 0; i < len; i++) { | |
304 if (CBC_OnedCode39Reader::ALPHABET_STRING[i] == encodedContents[l])
{ | |
305 ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[i], widths)
; | |
306 pos += AppendPattern(result, pos, widths, 9, 1, e); | |
307 if (e != BCExceptionNO) { | |
308 FX_Free (result); | |
309 return NULL; | |
310 } | |
311 } | |
312 } | |
313 pos += AppendPattern(result, pos, narrowWhite, 1, 0, e); | |
314 if (e != BCExceptionNO) { | |
315 FX_Free (result); | |
316 return NULL; | |
317 } | |
318 } | |
319 ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[39], widths); | |
320 pos += AppendPattern(result, pos, widths, 9, 1, e); | |
321 if (e != BCExceptionNO) { | |
322 FX_Free (result); | |
323 return NULL; | |
324 } | |
325 for (FX_INT32 i = 0; i < codeWidth / 2; i++) { | |
326 result[i] ^= result[codeWidth - 1 - i]; | |
327 result[codeWidth - 1 - i] ^= result[i]; | |
328 result[i] ^= result[codeWidth - 1 - i]; | |
329 } | |
330 return result; | |
331 } | |
332 CFX_WideString CBC_OnedCode39Writer::encodedContents(FX_WSTR contents, FX_INT32
&e) | |
333 { | |
334 CFX_WideString encodedContents = contents; | |
335 if (m_bCalcChecksum && m_bPrintChecksum) { | |
336 CFX_WideString checksumContent = FilterContents(contents); | |
337 CFX_ByteString str = checksumContent.UTF8Encode(); | |
338 FX_CHAR checksum; | |
339 checksum = CalcCheckSum(str, e); | |
340 BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); | |
341 str += checksum; | |
342 encodedContents += checksum; | |
343 } | |
344 return encodedContents; | |
345 } | |
346 void CBC_OnedCode39Writer::RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT3
2 codeLength, FX_BOOL isDevice, FX_INT32 &e) | |
347 { | |
348 CFX_WideString encodedCon = encodedContents(contents, e); | |
349 BC_EXCEPTION_CHECK_ReturnVoid(e); | |
350 CBC_OneDimWriter::RenderResult(encodedCon, code, codeLength, isDevice, e); | |
351 } | |
OLD | NEW |