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 2007 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/qrcode/BC_QRCoderMode.h"
24
25#include <utility>
26
27#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
28#include "xfa/fxbarcode/utils.h"
29
30CBC_QRCoderMode* CBC_QRCoderMode::sBYTE = nullptr;
31CBC_QRCoderMode* CBC_QRCoderMode::sNUMERIC = nullptr;
32CBC_QRCoderMode* CBC_QRCoderMode::sALPHANUMERIC = nullptr;
33CBC_QRCoderMode* CBC_QRCoderMode::sKANJI = nullptr;
34CBC_QRCoderMode* CBC_QRCoderMode::sECI = nullptr;
35CBC_QRCoderMode* CBC_QRCoderMode::sGBK = nullptr;
36CBC_QRCoderMode* CBC_QRCoderMode::sTERMINATOR = nullptr;
37CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_FIRST_POSITION = nullptr;
38CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_SECOND_POSITION = nullptr;
39CBC_QRCoderMode* CBC_QRCoderMode::sSTRUCTURED_APPEND = nullptr;
40
41CBC_QRCoderMode::CBC_QRCoderMode(std::vector<int32_t> charCountBits,
42                                 int32_t bits,
43                                 CFX_ByteString name)
44    : m_characterCountBitsForVersions(std::move(charCountBits)),
45      m_bits(bits),
46      m_name(name) {}
47
48CBC_QRCoderMode::~CBC_QRCoderMode() {}
49
50void CBC_QRCoderMode::Initialize() {
51  sBYTE = new CBC_QRCoderMode({8, 16, 16}, 0x4, "BYTE");
52  sALPHANUMERIC = new CBC_QRCoderMode({9, 11, 13}, 0x2, "ALPHANUMERIC");
53  sECI = new CBC_QRCoderMode(std::vector<int32_t>(), 0x7, "ECI");
54  sKANJI = new CBC_QRCoderMode({8, 10, 12}, 0x8, "KANJI");
55  sNUMERIC = new CBC_QRCoderMode({10, 12, 14}, 0x1, "NUMERIC");
56  sGBK = new CBC_QRCoderMode({8, 10, 12}, 0x0D, "GBK");
57  sTERMINATOR = new CBC_QRCoderMode(std::vector<int32_t>(), 0x00, "TERMINATOR");
58  sFNC1_FIRST_POSITION =
59      new CBC_QRCoderMode(std::vector<int32_t>(), 0x05, "FNC1_FIRST_POSITION");
60  sFNC1_SECOND_POSITION =
61      new CBC_QRCoderMode(std::vector<int32_t>(), 0x09, "FNC1_SECOND_POSITION");
62  sSTRUCTURED_APPEND =
63      new CBC_QRCoderMode(std::vector<int32_t>(), 0x03, "STRUCTURED_APPEND");
64}
65
66void CBC_QRCoderMode::Finalize() {
67  delete sBYTE;
68  delete sALPHANUMERIC;
69  delete sECI;
70  delete sKANJI;
71  delete sNUMERIC;
72  delete sGBK;
73  delete sTERMINATOR;
74  delete sFNC1_FIRST_POSITION;
75  delete sFNC1_SECOND_POSITION;
76  delete sSTRUCTURED_APPEND;
77}
78
79CBC_QRCoderMode* CBC_QRCoderMode::ForBits(int32_t bits, int32_t& e) {
80  switch (bits) {
81    case 0x0:
82      return sTERMINATOR;
83    case 0x1:
84      return sNUMERIC;
85    case 0x2:
86      return sALPHANUMERIC;
87    case 0x3:
88      return sSTRUCTURED_APPEND;
89    case 0x4:
90      return sBYTE;
91    case 0x5:
92      return sFNC1_FIRST_POSITION;
93    case 0x7:
94      return sECI;
95    case 0x8:
96      return sKANJI;
97    case 0x9:
98      return sFNC1_SECOND_POSITION;
99    case 0x0D:
100      return sGBK;
101    default:
102      e = BCExceptionUnsupportedMode;
103      return nullptr;
104  }
105}
106
107int32_t CBC_QRCoderMode::GetBits() const {
108  return m_bits;
109}
110
111CFX_ByteString CBC_QRCoderMode::GetName() const {
112  return m_name;
113}
114
115int32_t CBC_QRCoderMode::GetCharacterCountBits(CBC_QRCoderVersion* version,
116                                               int32_t& e) const {
117  if (m_characterCountBitsForVersions.empty()) {
118    e = BCExceptionCharacterNotThisMode;
119    return 0;
120  }
121  int32_t number = version->GetVersionNumber();
122  int32_t offset;
123  if (number <= 9) {
124    offset = 0;
125  } else if (number <= 26) {
126    offset = 1;
127  } else {
128    offset = 2;
129  }
130  return m_characterCountBitsForVersions[offset];
131}
132
133void CBC_QRCoderMode::Destroy() {
134  if (sBYTE) {
135    delete CBC_QRCoderMode::sBYTE;
136    sBYTE = nullptr;
137  }
138  if (sNUMERIC) {
139    delete CBC_QRCoderMode::sNUMERIC;
140    sNUMERIC = nullptr;
141  }
142  if (sALPHANUMERIC) {
143    delete CBC_QRCoderMode::sALPHANUMERIC;
144    sALPHANUMERIC = nullptr;
145  }
146  if (sKANJI) {
147    delete CBC_QRCoderMode::sKANJI;
148    sKANJI = nullptr;
149  }
150  if (sECI) {
151    delete CBC_QRCoderMode::sECI;
152    sECI = nullptr;
153  }
154  if (sGBK) {
155    delete CBC_QRCoderMode::sGBK;
156    sGBK = nullptr;
157  }
158  if (sTERMINATOR) {
159    delete CBC_QRCoderMode::sTERMINATOR;
160    sTERMINATOR = nullptr;
161  }
162  if (sFNC1_FIRST_POSITION) {
163    delete CBC_QRCoderMode::sFNC1_FIRST_POSITION;
164    sFNC1_FIRST_POSITION = nullptr;
165  }
166  if (sFNC1_SECOND_POSITION) {
167    delete CBC_QRCoderMode::sFNC1_SECOND_POSITION;
168    sFNC1_SECOND_POSITION = nullptr;
169  }
170  if (sSTRUCTURED_APPEND) {
171    delete CBC_QRCoderMode::sSTRUCTURED_APPEND;
172    sSTRUCTURED_APPEND = nullptr;
173  }
174}
175