1 #pragma once
2 /*
3 * Copyright 2016 Huy Cuong Nguyen
4 * Copyright 2016 ZXing authors
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 #include "CharacterSet.h"
19 #include "PDFCompaction.h"
20 #include "ZXContainerAlgorithms.h"
21 
22 #include <string>
23 #include <vector>
24 
25 namespace ZXing {
26 
27 namespace Pdf417 {
28 
29 /**
30 * @author Jacob Haynes
31 */
32 class BarcodeRow
33 {
34 	std::vector<bool> _row;
35 	int _currentLocation = 0; // A tacker for position in the bar
36 
37 public:
_row(width,false)38 	explicit BarcodeRow(int width = 0) : _row(width, false) {}
39 
init(int width)40 	void init(int width) {
41 		_row.resize(width, false);
42 		_currentLocation = 0;
43 	}
44 
set(int x,bool black)45 	void set(int x, bool black) {
46 		_row.at(x) = black;
47 	}
48 
49 	/**
50 	* @param black A boolean which is true if the bar black false if it is white
51 	* @param width How many spots wide the bar is.
52 	*/
addBar(bool black,int width)53 	void addBar(bool black, int width) {
54 		for (int ii = 0; ii < width; ii++) {
55 			_row.at(_currentLocation++) = black;
56 		}
57 	}
58 
59 	/**
60 	* This function scales the row
61 	*
62 	* @param scale How much you want the image to be scaled, must be greater than or equal to 1.
63 	* @return the scaled row
64 	*/
getScaledRow(int scale,std::vector<bool> & output)65 	void getScaledRow(int scale, std::vector<bool>& output) const {
66 		output.resize(_row.size() * scale);
67 		for (size_t i = 0; i < output.size(); ++i) {
68 			output[i] = _row[i / scale];
69 		}
70 	}
71 };
72 
73 /**
74 * Holds all of the information for a barcode in a format where it can be easily accessable
75 *
76 * @author Jacob Haynes
77 */
78 class BarcodeMatrix
79 {
80 	std::vector<BarcodeRow> _matrix;
81 	int _width = 0;
82 	int _currentRow = -1;
83 
84 public:
BarcodeMatrix()85 	BarcodeMatrix() {}
86 
87 	/**
88 	* @param height the height of the matrix (Rows)
89 	* @param width  the width of the matrix (Cols)
90 	*/
BarcodeMatrix(int height,int width)91 	BarcodeMatrix(int height, int width) {
92 		init(height, width);
93 	}
94 
init(int height,int width)95 	void init(int height, int width) {
96 		_matrix.resize(height);
97 		for (int i = 0; i < height; ++i) {
98 			_matrix[i].init((width + 4) * 17 + 1);
99 		}
100 		_width = width * 17;
101 		_currentRow = -1;
102 	}
103 
set(int x,int y,bool value)104 	void set(int x, int y, bool value) {
105 		_matrix[y].set(x, value);
106 	}
107 
startRow()108 	void startRow() {
109 		++_currentRow;
110 	}
111 
currentRow()112 	const BarcodeRow& currentRow() const {
113 		return _matrix[_currentRow];
114 	}
115 
currentRow()116 	BarcodeRow& currentRow() {
117 		return _matrix[_currentRow];
118 	}
119 
getScaledMatrix(int xScale,int yScale,std::vector<std::vector<bool>> & output)120 	void getScaledMatrix(int xScale, int yScale, std::vector<std::vector<bool>>& output)
121 	{
122 		output.resize(_matrix.size() * yScale);
123 		int yMax = Size(output);
124 		for (int i = 0; i < yMax; i++) {
125 			_matrix[i / yScale].getScaledRow(xScale, output[yMax - i - 1]);
126 		}
127 	}
128 };
129 
130 /**
131 * Top-level class for the logic part of the PDF417 implementation.
132 * C++ port: this class was named PDF417 in Java code. Since that name
133 * does say much in the context of PDF417 writer, it's renamed here Encoder
134 * to follow the same naming convention with other modules.
135 */
136 class Encoder
137 {
138 public:
_compact(compact)139 	explicit Encoder(bool compact = false) : _compact(compact)  {}
140 
141 	BarcodeMatrix generateBarcodeLogic(const std::wstring& msg, int errorCorrectionLevel) const;
142 
143 	/**
144 	* Sets max/min row/col values
145 	*
146 	* @param maxCols maximum allowed columns
147 	* @param minCols minimum allowed columns
148 	* @param maxRows maximum allowed rows
149 	* @param minRows minimum allowed rows
150 	*/
setDimensions(int minCols,int maxCols,int minRows,int maxRows)151 	void setDimensions(int minCols, int maxCols, int minRows, int maxRows) {
152 		_minCols = minCols;
153 		_maxCols = maxCols;
154 		_minRows = minRows;
155 		_maxRows = maxRows;
156 	}
157 
158 	/**
159 	* @param compaction compaction mode to use
160 	*/
setCompaction(Compaction compaction)161 	void setCompaction(Compaction compaction) {
162 		_compaction = compaction;
163 	}
164 
165 	/**
166 	* @param compact if true, enables compaction
167 	*/
setCompact(bool compact)168 	void setCompact(bool compact) {
169 		_compact = compact;
170 	}
171 
172 	/**
173 	* @param encoding sets character encoding to use
174 	*/
setEncoding(CharacterSet encoding)175 	void setEncoding(CharacterSet encoding) {
176 		_encoding = encoding;
177 	}
178 
179 	static int GetRecommendedMinimumErrorCorrectionLevel(int n);
180 
181 private:
182 	bool _compact;
183 	Compaction _compaction = Compaction::AUTO;
184 	CharacterSet _encoding = CharacterSet::ISO8859_1;
185 	int _minCols = 2;
186 	int _maxCols = 30;
187 	int _minRows = 2;
188 	int _maxRows = 30;
189 };
190 
191 } // Pdf417
192 } // ZXing
193