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/barcode.h"
24 #include "xfa/src/fxbarcode/BC_Writer.h"
25 #include "xfa/src/fxbarcode/BC_Reader.h"
26 #include "BC_OneDReader.h"
27 #include "BC_OneDimWriter.h"
28 #include "BC_OnedCode128Reader.h"
29 #include "BC_OnedCode128Writer.h"
30 const int32_t CBC_OnedCode128Writer::CODE_CODE_B = 100;
31 const int32_t CBC_OnedCode128Writer::CODE_CODE_C = 99;
32 const int32_t CBC_OnedCode128Writer::CODE_START_B = 104;
33 const int32_t CBC_OnedCode128Writer::CODE_START_C = 105;
34 const int32_t CBC_OnedCode128Writer::CODE_STOP = 106;
CBC_OnedCode128Writer()35 CBC_OnedCode128Writer::CBC_OnedCode128Writer() {
36   m_codeFormat = BC_CODE128_B;
37 }
CBC_OnedCode128Writer(BC_TYPE type)38 CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type) {
39   m_codeFormat = type;
40 }
~CBC_OnedCode128Writer()41 CBC_OnedCode128Writer::~CBC_OnedCode128Writer() {}
GetType()42 BC_TYPE CBC_OnedCode128Writer::GetType() {
43   return m_codeFormat;
44 }
CheckContentValidity(const CFX_WideStringC & contents)45 FX_BOOL CBC_OnedCode128Writer::CheckContentValidity(
46     const CFX_WideStringC& contents) {
47   FX_BOOL ret = TRUE;
48   int32_t position = 0;
49   int32_t patternIndex = -1;
50   if (m_codeFormat == BC_CODE128_B || m_codeFormat == BC_CODE128_C) {
51     while (position < contents.GetLength()) {
52       patternIndex = (int32_t)contents.GetAt(position);
53       if (patternIndex >= 32 && patternIndex <= 126 && patternIndex != 34) {
54         position++;
55         continue;
56       } else {
57         ret = FALSE;
58         break;
59       }
60       position++;
61     }
62   } else {
63     ret = FALSE;
64   }
65   return ret;
66 }
FilterContents(const CFX_WideStringC & contents)67 CFX_WideString CBC_OnedCode128Writer::FilterContents(
68     const CFX_WideStringC& contents) {
69   CFX_WideString filterChineseChar;
70   FX_WCHAR ch;
71   for (int32_t i = 0; i < contents.GetLength(); i++) {
72     ch = contents.GetAt(i);
73     if (ch > 175) {
74       i++;
75       continue;
76     }
77     filterChineseChar += ch;
78   }
79   CFX_WideString filtercontents;
80   if (m_codeFormat == BC_CODE128_B) {
81     for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) {
82       ch = filterChineseChar.GetAt(i);
83       if (ch >= 32 && ch <= 126) {
84         filtercontents += ch;
85       } else {
86         continue;
87       }
88     }
89   } else if (m_codeFormat == BC_CODE128_C) {
90     for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) {
91       ch = filterChineseChar.GetAt(i);
92       if (ch >= 32 && ch <= 106) {
93         filtercontents += ch;
94       } else {
95         continue;
96       }
97     }
98   } else {
99     filtercontents = contents;
100   }
101   return filtercontents;
102 }
SetTextLocation(BC_TEXT_LOC location)103 FX_BOOL CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location) {
104   if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {
105     return FALSE;
106   }
107   m_locTextLoc = location;
108   return TRUE;
109 }
Encode(const CFX_ByteString & contents,BCFORMAT format,int32_t & outWidth,int32_t & outHeight,int32_t hints,int32_t & e)110 uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
111                                        BCFORMAT format,
112                                        int32_t& outWidth,
113                                        int32_t& outHeight,
114                                        int32_t hints,
115                                        int32_t& e) {
116   if (format != BCFORMAT_CODE_128) {
117     e = BCExceptionOnlyEncodeCODE_128;
118     return NULL;
119   }
120   uint8_t* ret =
121       CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
122   BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
123   return ret;
124 }
Encode(const CFX_ByteString & contents,BCFORMAT format,int32_t & outWidth,int32_t & outHeight,int32_t & e)125 uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
126                                        BCFORMAT format,
127                                        int32_t& outWidth,
128                                        int32_t& outHeight,
129                                        int32_t& e) {
130   uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e);
131   BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
132   return ret;
133 }
IsDigits(const CFX_ByteString & contents,int32_t start,int32_t length)134 FX_BOOL CBC_OnedCode128Writer::IsDigits(const CFX_ByteString& contents,
135                                         int32_t start,
136                                         int32_t length) {
137   int32_t end = start + length;
138   for (int32_t i = start; i < end; i++) {
139     if (contents[i] < '0' || contents[i] > '9') {
140       return FALSE;
141     }
142   }
143   return TRUE;
144 }
Encode(const CFX_ByteString & contents,int32_t & outLength,int32_t & e)145 uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents,
146                                        int32_t& outLength,
147                                        int32_t& e) {
148   if (contents.GetLength() < 1 || contents.GetLength() > 80) {
149     e = BCExceptionContentsLengthShouldBetween1and80;
150     return NULL;
151   }
152   CFX_PtrArray patterns;
153   int32_t checkSum = 0;
154   if (m_codeFormat == BC_CODE128_B) {
155     checkSum = Encode128B(contents, patterns);
156   } else if (m_codeFormat == BC_CODE128_C) {
157     checkSum = Encode128C(contents, patterns);
158   } else {
159     e = BCExceptionFormatException;
160     return NULL;
161   }
162   checkSum %= 103;
163   patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[checkSum]);
164   patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_STOP]);
165   m_iContentLen = contents.GetLength() + 3;
166   int32_t codeWidth = 0;
167   for (int32_t k = 0; k < patterns.GetSize(); k++) {
168     int32_t* pattern = (int32_t*)patterns[k];
169     for (int32_t j = 0; j < 7; j++) {
170       codeWidth += pattern[j];
171     }
172   }
173   outLength = codeWidth;
174   uint8_t* result = FX_Alloc(uint8_t, outLength);
175   int32_t pos = 0;
176   for (int32_t j = 0; j < patterns.GetSize(); j++) {
177     int32_t* pattern = (int32_t*)patterns[j];
178     pos += AppendPattern(result, pos, pattern, 7, 1, e);
179     if (e != BCExceptionNO) {
180       FX_Free(result);
181       return NULL;
182     }
183   }
184   return result;
185 }
Encode128B(const CFX_ByteString & contents,CFX_PtrArray & patterns)186 int32_t CBC_OnedCode128Writer::Encode128B(const CFX_ByteString& contents,
187                                           CFX_PtrArray& patterns) {
188   int32_t checkSum = 0;
189   int32_t checkWeight = 1;
190   int32_t position = 0;
191   patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_B]);
192   checkSum += CODE_START_B * checkWeight;
193   while (position < contents.GetLength()) {
194     int32_t patternIndex = 0;
195     patternIndex = contents[position] - ' ';
196     position += 1;
197     patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);
198     checkSum += patternIndex * checkWeight;
199     if (position != 0) {
200       checkWeight++;
201     }
202   }
203   return checkSum;
204 }
Encode128C(const CFX_ByteString & contents,CFX_PtrArray & patterns)205 int32_t CBC_OnedCode128Writer::Encode128C(const CFX_ByteString& contents,
206                                           CFX_PtrArray& patterns) {
207   int32_t checkSum = 0;
208   int32_t checkWeight = 1;
209   int32_t position = 0;
210   patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_C]);
211   checkSum += CODE_START_C * checkWeight;
212   while (position < contents.GetLength()) {
213     int32_t patternIndex = 0;
214     FX_CHAR ch = contents.GetAt(position);
215     if (ch < '0' || ch > '9') {
216       patternIndex = (int32_t)ch;
217       position++;
218     } else {
219       patternIndex = FXSYS_atoi(contents.Mid(position, 2));
220       if (contents.GetAt(position + 1) < '0' ||
221           contents.GetAt(position + 1) > '9') {
222         position += 1;
223       } else {
224         position += 2;
225       }
226     }
227     patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);
228     checkSum += patternIndex * checkWeight;
229     if (position != 0) {
230       checkWeight++;
231     }
232   }
233   return checkSum;
234 }
235