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