• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/fxbarcode/BC_Writer.h"
24 #include "xfa/fxbarcode/oned/BC_OneDimWriter.h"
25 #include "xfa/fxbarcode/oned/BC_OnedCode128Writer.h"
26 
27 namespace {
28 
29 const 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 
67 const int32_t CODE_START_B = 104;
68 const int32_t CODE_START_C = 105;
69 const int32_t CODE_STOP = 106;
70 
71 }  // namespace
72 
CBC_OnedCode128Writer()73 CBC_OnedCode128Writer::CBC_OnedCode128Writer() {
74   m_codeFormat = BC_CODE128_B;
75 }
CBC_OnedCode128Writer(BC_TYPE type)76 CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type) {
77   m_codeFormat = type;
78 }
~CBC_OnedCode128Writer()79 CBC_OnedCode128Writer::~CBC_OnedCode128Writer() {}
GetType()80 BC_TYPE CBC_OnedCode128Writer::GetType() {
81   return m_codeFormat;
82 }
CheckContentValidity(const CFX_WideStringC & contents)83 bool CBC_OnedCode128Writer::CheckContentValidity(
84     const CFX_WideStringC& contents) {
85   bool ret = true;
86   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);
91       if (patternIndex < 32 || patternIndex > 126 || patternIndex == 34) {
92         ret = false;
93         break;
94       }
95       position++;
96     }
97   } else {
98     ret = false;
99   }
100   return ret;
101 }
FilterContents(const CFX_WideStringC & contents)102 CFX_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 }
SetTextLocation(BC_TEXT_LOC location)138 bool CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location) {
139   if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {
140     return false;
141   }
142   m_locTextLoc = location;
143   return true;
144 }
Encode(const CFX_ByteString & contents,BCFORMAT format,int32_t & outWidth,int32_t & outHeight,int32_t hints,int32_t & e)145 uint8_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;
153     return nullptr;
154   }
155   uint8_t* ret =
156       CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
157   if (e != BCExceptionNO)
158     return nullptr;
159   return ret;
160 }
Encode(const CFX_ByteString & contents,BCFORMAT format,int32_t & outWidth,int32_t & outHeight,int32_t & e)161 uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
162                                        BCFORMAT format,
163                                        int32_t& outWidth,
164                                        int32_t& outHeight,
165                                        int32_t& e) {
166   uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e);
167   if (e != BCExceptionNO)
168     return nullptr;
169   return ret;
170 }
IsDigits(const CFX_ByteString & contents,int32_t start,int32_t length)171 bool CBC_OnedCode128Writer::IsDigits(const CFX_ByteString& contents,
172                                      int32_t start,
173                                      int32_t length) {
174   int32_t end = start + length;
175   for (int32_t i = start; i < end; i++) {
176     if (contents[i] < '0' || contents[i] > '9') {
177       return false;
178     }
179   }
180   return true;
181 }
182 
Encode(const CFX_ByteString & contents,int32_t & outLength,int32_t & e)183 uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
184                                        int32_t& outLength,
185                                        int32_t& e) {
186   if (contents.GetLength() < 1 || contents.GetLength() > 80) {
187     e = BCExceptionContentsLengthShouldBetween1and80;
188     return nullptr;
189   }
190   CFX_ArrayTemplate<const int32_t*> patterns;
191   int32_t checkSum = 0;
192   if (m_codeFormat == BC_CODE128_B) {
193     checkSum = Encode128B(contents, &patterns);
194   } else if (m_codeFormat == BC_CODE128_C) {
195     checkSum = Encode128C(contents, &patterns);
196   } else {
197     e = BCExceptionFormatException;
198     return nullptr;
199   }
200   checkSum %= 103;
201   patterns.Add(CODE_PATTERNS[checkSum]);
202   patterns.Add(CODE_PATTERNS[CODE_STOP]);
203   m_iContentLen = contents.GetLength() + 3;
204   int32_t codeWidth = 0;
205   for (int32_t k = 0; k < patterns.GetSize(); k++) {
206     const int32_t* pattern = patterns[k];
207     for (int32_t j = 0; j < 7; j++) {
208       codeWidth += pattern[j];
209     }
210   }
211   outLength = codeWidth;
212   uint8_t* result = FX_Alloc(uint8_t, outLength);
213   int32_t pos = 0;
214   for (int32_t j = 0; j < patterns.GetSize(); j++) {
215     const int32_t* pattern = patterns[j];
216     pos += AppendPattern(result, pos, pattern, 7, 1, e);
217     if (e != BCExceptionNO) {
218       FX_Free(result);
219       return nullptr;
220     }
221   }
222   return result;
223 }
224 
Encode128B(const CFX_ByteString & contents,CFX_ArrayTemplate<const int32_t * > * patterns)225 int32_t CBC_OnedCode128Writer::Encode128B(
226     const CFX_ByteString& contents,
227     CFX_ArrayTemplate<const int32_t*>* patterns) {
228   int32_t checkSum = 0;
229   int32_t checkWeight = 1;
230   int32_t position = 0;
231   patterns->Add(CODE_PATTERNS[CODE_START_B]);
232   checkSum += CODE_START_B * checkWeight;
233   while (position < contents.GetLength()) {
234     int32_t patternIndex = 0;
235     patternIndex = contents[position] - ' ';
236     position += 1;
237     patterns->Add(CODE_PATTERNS[patternIndex]);
238     checkSum += patternIndex * checkWeight;
239     if (position != 0) {
240       checkWeight++;
241     }
242   }
243   return checkSum;
244 }
245 
Encode128C(const CFX_ByteString & contents,CFX_ArrayTemplate<const int32_t * > * patterns)246 int32_t CBC_OnedCode128Writer::Encode128C(
247     const CFX_ByteString& contents,
248     CFX_ArrayTemplate<const int32_t*>* patterns) {
249   int32_t checkSum = 0;
250   int32_t checkWeight = 1;
251   int32_t position = 0;
252   patterns->Add(CODE_PATTERNS[CODE_START_C]);
253   checkSum += CODE_START_C * checkWeight;
254   while (position < contents.GetLength()) {
255     int32_t patternIndex = 0;
256     FX_CHAR ch = contents.GetAt(position);
257     if (ch < '0' || ch > '9') {
258       patternIndex = (int32_t)ch;
259       position++;
260     } else {
261       patternIndex = FXSYS_atoi(contents.Mid(position, 2).c_str());
262       if (contents.GetAt(position + 1) < '0' ||
263           contents.GetAt(position + 1) > '9') {
264         position += 1;
265       } else {
266         position += 2;
267       }
268     }
269     patterns->Add(CODE_PATTERNS[patternIndex]);
270     checkSum += patternIndex * checkWeight;
271     if (position != 0) {
272       checkWeight++;
273     }
274   }
275   return checkSum;
276 }
277