Prison

code93barcode.cpp
1/*
2 SPDX-FileCopyrightText: 2011 Geoffry Song <goffrie@gmail.com>
3
4 SPDX-License-Identifier: MIT
5*/
6
7#include "barcodeutil_p.h"
8#include "code93barcode_p.h"
9#include <QChar>
10
11using namespace Prison;
12
13// returns a list of 9 bar colors, where `true' means foreground and `false' means background color
14static QList<bool> sequenceForID(int id)
15{
16 switch (id) {
17 case 0:
18 return BarCodeUtil::barSequence("100010100"); // 0-9
19 case 1:
20 return BarCodeUtil::barSequence("101001000");
21 case 2:
22 return BarCodeUtil::barSequence("101000100");
23 case 3:
24 return BarCodeUtil::barSequence("101000010");
25 case 4:
26 return BarCodeUtil::barSequence("100101000");
27 case 5:
28 return BarCodeUtil::barSequence("100100100");
29 case 6:
30 return BarCodeUtil::barSequence("100100010");
31 case 7:
32 return BarCodeUtil::barSequence("101010000");
33 case 8:
34 return BarCodeUtil::barSequence("100010010");
35 case 9:
36 return BarCodeUtil::barSequence("100001010");
37 case 10:
38 return BarCodeUtil::barSequence("110101000"); // A-Z
39 case 11:
40 return BarCodeUtil::barSequence("110100100");
41 case 12:
42 return BarCodeUtil::barSequence("110100010");
43 case 13:
44 return BarCodeUtil::barSequence("110010100");
45 case 14:
46 return BarCodeUtil::barSequence("110010010");
47 case 15:
48 return BarCodeUtil::barSequence("110001010");
49 case 16:
50 return BarCodeUtil::barSequence("101101000");
51 case 17:
52 return BarCodeUtil::barSequence("101100100");
53 case 18:
54 return BarCodeUtil::barSequence("101100010");
55 case 19:
56 return BarCodeUtil::barSequence("100110100");
57 case 20:
58 return BarCodeUtil::barSequence("100011010");
59 case 21:
60 return BarCodeUtil::barSequence("101011000");
61 case 22:
62 return BarCodeUtil::barSequence("101001100");
63 case 23:
64 return BarCodeUtil::barSequence("101000110");
65 case 24:
66 return BarCodeUtil::barSequence("100101100");
67 case 25:
68 return BarCodeUtil::barSequence("100010110");
69 case 26:
70 return BarCodeUtil::barSequence("110110100");
71 case 27:
72 return BarCodeUtil::barSequence("110110010");
73 case 28:
74 return BarCodeUtil::barSequence("110101100");
75 case 29:
76 return BarCodeUtil::barSequence("110100110");
77 case 30:
78 return BarCodeUtil::barSequence("110010110");
79 case 31:
80 return BarCodeUtil::barSequence("110011010");
81 case 32:
82 return BarCodeUtil::barSequence("101101100");
83 case 33:
84 return BarCodeUtil::barSequence("101100110");
85 case 34:
86 return BarCodeUtil::barSequence("100110110");
87 case 35:
88 return BarCodeUtil::barSequence("100111010");
89 case 36:
90 return BarCodeUtil::barSequence("100101110"); // -
91 case 37:
92 return BarCodeUtil::barSequence("111010100"); // .
93 case 38:
94 return BarCodeUtil::barSequence("111010010"); // space
95 case 39:
96 return BarCodeUtil::barSequence("111001010"); // $
97 case 40:
98 return BarCodeUtil::barSequence("101101110"); // /
99 case 41:
100 return BarCodeUtil::barSequence("101110110"); // +
101 case 42:
102 return BarCodeUtil::barSequence("110101110"); // $
103 case 43:
104 return BarCodeUtil::barSequence("100100110"); // ($)
105 case 44:
106 return BarCodeUtil::barSequence("111011010"); // (%)
107 case 45:
108 return BarCodeUtil::barSequence("111010110"); // (/)
109 case 46:
110 return BarCodeUtil::barSequence("100110010"); // (+)
111 case 47:
112 return BarCodeUtil::barSequence("101011110"); // stop sequence
113 default:
114 // unknown ID... shouldn't happen
115 qWarning("Code93Barcode::sequenceForID called with unknown ID");
116 return QList<bool>();
117 }
118}
119
120// returns the list of IDs that represent a character
121static QList<int> codesForChar(uint c)
122{
123 QList<int> ret;
124 switch (c) {
125 case 0:
126 ret += 44;
127 ret += 30;
128 break;
129 case 1:
130 ret += 43;
131 ret += 10;
132 break;
133 case 2:
134 ret += 43;
135 ret += 11;
136 break;
137 case 3:
138 ret += 43;
139 ret += 12;
140 break;
141 case 4:
142 ret += 43;
143 ret += 13;
144 break;
145 case 5:
146 ret += 43;
147 ret += 14;
148 break;
149 case 6:
150 ret += 43;
151 ret += 15;
152 break;
153 case 7:
154 ret += 43;
155 ret += 16;
156 break;
157 case 8:
158 ret += 43;
159 ret += 17;
160 break;
161 case 9:
162 ret += 43;
163 ret += 18;
164 break;
165 case 10:
166 ret += 43;
167 ret += 19;
168 break;
169 case 11:
170 ret += 43;
171 ret += 20;
172 break;
173 case 12:
174 ret += 43;
175 ret += 21;
176 break;
177 case 13:
178 ret += 43;
179 ret += 22;
180 break;
181 case 14:
182 ret += 43;
183 ret += 23;
184 break;
185 case 15:
186 ret += 43;
187 ret += 24;
188 break;
189 case 16:
190 ret += 43;
191 ret += 25;
192 break;
193 case 17:
194 ret += 43;
195 ret += 26;
196 break;
197 case 18:
198 ret += 43;
199 ret += 27;
200 break;
201 case 19:
202 ret += 43;
203 ret += 28;
204 break;
205 case 20:
206 ret += 43;
207 ret += 29;
208 break;
209 case 21:
210 ret += 43;
211 ret += 30;
212 break;
213 case 22:
214 ret += 43;
215 ret += 31;
216 break;
217 case 23:
218 ret += 43;
219 ret += 32;
220 break;
221 case 24:
222 ret += 43;
223 ret += 33;
224 break;
225 case 25:
226 ret += 43;
227 ret += 34;
228 break;
229 case 26:
230 ret += 43;
231 ret += 35;
232 break;
233 case 27:
234 ret += 44;
235 ret += 10;
236 break;
237 case 28:
238 ret += 44;
239 ret += 11;
240 break;
241 case 29:
242 ret += 44;
243 ret += 12;
244 break;
245 case 30:
246 ret += 44;
247 ret += 13;
248 break;
249 case 31:
250 ret += 44;
251 ret += 14;
252 break;
253 case 32:
254 ret += 38;
255 break;
256 case 33:
257 ret += 45;
258 ret += 10;
259 break;
260 case 34:
261 ret += 45;
262 ret += 11;
263 break;
264 case 35:
265 ret += 45;
266 ret += 12;
267 break;
268 case 36:
269 ret += 39;
270 break;
271 case 37:
272 ret += 42;
273 break;
274 case 38:
275 ret += 45;
276 ret += 15;
277 break;
278 case 39:
279 ret += 45;
280 ret += 16;
281 break;
282 case 40:
283 ret += 45;
284 ret += 17;
285 break;
286 case 41:
287 ret += 45;
288 ret += 18;
289 break;
290 case 42:
291 ret += 45;
292 ret += 19;
293 break;
294 case 43:
295 ret += 41;
296 break;
297 case 44:
298 ret += 45;
299 ret += 21;
300 break;
301 case 45:
302 ret += 36;
303 break;
304 case 46:
305 ret += 37;
306 break;
307 case 47:
308 ret += 40;
309 break;
310 case 48:
311 ret += 0;
312 break;
313 case 49:
314 ret += 1;
315 break;
316 case 50:
317 ret += 2;
318 break;
319 case 51:
320 ret += 3;
321 break;
322 case 52:
323 ret += 4;
324 break;
325 case 53:
326 ret += 5;
327 break;
328 case 54:
329 ret += 6;
330 break;
331 case 55:
332 ret += 7;
333 break;
334 case 56:
335 ret += 8;
336 break;
337 case 57:
338 ret += 9;
339 break;
340 case 58:
341 ret += 45;
342 ret += 35;
343 break;
344 case 59:
345 ret += 44;
346 ret += 15;
347 break;
348 case 60:
349 ret += 44;
350 ret += 16;
351 break;
352 case 61:
353 ret += 44;
354 ret += 17;
355 break;
356 case 62:
357 ret += 44;
358 ret += 18;
359 break;
360 case 63:
361 ret += 44;
362 ret += 19;
363 break;
364 case 64:
365 ret += 44;
366 ret += 31;
367 break;
368 case 65:
369 ret += 10;
370 break;
371 case 66:
372 ret += 11;
373 break;
374 case 67:
375 ret += 12;
376 break;
377 case 68:
378 ret += 13;
379 break;
380 case 69:
381 ret += 14;
382 break;
383 case 70:
384 ret += 15;
385 break;
386 case 71:
387 ret += 16;
388 break;
389 case 72:
390 ret += 17;
391 break;
392 case 73:
393 ret += 18;
394 break;
395 case 74:
396 ret += 19;
397 break;
398 case 75:
399 ret += 20;
400 break;
401 case 76:
402 ret += 21;
403 break;
404 case 77:
405 ret += 22;
406 break;
407 case 78:
408 ret += 23;
409 break;
410 case 79:
411 ret += 24;
412 break;
413 case 80:
414 ret += 25;
415 break;
416 case 81:
417 ret += 26;
418 break;
419 case 82:
420 ret += 27;
421 break;
422 case 83:
423 ret += 28;
424 break;
425 case 84:
426 ret += 29;
427 break;
428 case 85:
429 ret += 30;
430 break;
431 case 86:
432 ret += 31;
433 break;
434 case 87:
435 ret += 32;
436 break;
437 case 88:
438 ret += 33;
439 break;
440 case 89:
441 ret += 34;
442 break;
443 case 90:
444 ret += 35;
445 break;
446 case 91:
447 ret += 44;
448 ret += 20;
449 break;
450 case 92:
451 ret += 44;
452 ret += 21;
453 break;
454 case 93:
455 ret += 44;
456 ret += 22;
457 break;
458 case 94:
459 ret += 44;
460 ret += 23;
461 break;
462 case 95:
463 ret += 44;
464 ret += 24;
465 break;
466 case 96:
467 ret += 44;
468 ret += 32;
469 break;
470 case 97:
471 ret += 46;
472 ret += 10;
473 break;
474 case 98:
475 ret += 46;
476 ret += 11;
477 break;
478 case 99:
479 ret += 46;
480 ret += 12;
481 break;
482 case 100:
483 ret += 46;
484 ret += 13;
485 break;
486 case 101:
487 ret += 46;
488 ret += 14;
489 break;
490 case 102:
491 ret += 46;
492 ret += 15;
493 break;
494 case 103:
495 ret += 46;
496 ret += 16;
497 break;
498 case 104:
499 ret += 46;
500 ret += 17;
501 break;
502 case 105:
503 ret += 46;
504 ret += 18;
505 break;
506 case 106:
507 ret += 46;
508 ret += 19;
509 break;
510 case 107:
511 ret += 46;
512 ret += 20;
513 break;
514 case 108:
515 ret += 46;
516 ret += 21;
517 break;
518 case 109:
519 ret += 46;
520 ret += 22;
521 break;
522 case 110:
523 ret += 46;
524 ret += 23;
525 break;
526 case 111:
527 ret += 46;
528 ret += 24;
529 break;
530 case 112:
531 ret += 46;
532 ret += 25;
533 break;
534 case 113:
535 ret += 46;
536 ret += 26;
537 break;
538 case 114:
539 ret += 46;
540 ret += 27;
541 break;
542 case 115:
543 ret += 46;
544 ret += 28;
545 break;
546 case 116:
547 ret += 46;
548 ret += 29;
549 break;
550 case 117:
551 ret += 46;
552 ret += 30;
553 break;
554 case 118:
555 ret += 46;
556 ret += 31;
557 break;
558 case 119:
559 ret += 46;
560 ret += 32;
561 break;
562 case 120:
563 ret += 46;
564 ret += 33;
565 break;
566 case 121:
567 ret += 46;
568 ret += 34;
569 break;
570 case 122:
571 ret += 46;
572 ret += 35;
573 break;
574 case 123:
575 ret += 44;
576 ret += 25;
577 break;
578 case 124:
579 ret += 44;
580 ret += 26;
581 break;
582 case 125:
583 ret += 44;
584 ret += 27;
585 break;
586 case 126:
587 ret += 44;
588 ret += 28;
589 break;
590 case 127:
591 ret += 44;
592 ret += 29;
593 break;
594 }
595 return ret; // return an empty list for a non-ascii character code
596}
597
598// calculate a checksum
599static int checksum(const QList<int> &codes, int wrap)
600{
601 int check = 0;
602 for (int i = 0; i < codes.size(); i++) {
603 // weight goes from 1 to wrap, right-to-left, then repeats
604 const int weight = (codes.size() - i - 1) % wrap + 1;
605 check += codes.at(i) * weight;
606 }
607 return check % 47;
608}
609
610Code93Barcode::Code93Barcode()
611 : AbstractBarcodePrivate(Barcode::OneDimension)
612{
613}
614Code93Barcode::~Code93Barcode() = default;
615
616QImage Code93Barcode::paintImage()
617{
618 QList<bool> barcode;
619 // convert text into sequences of fg/bg bars
620 {
621 // translate the string into a code sequence
622 QList<int> codes;
623 const auto str = BarCodeUtil::asLatin1ByteArray(m_data);
624 for (int i = 0; i < str.size(); i++) {
625 codes += codesForChar(str.at(i));
626 }
627
628 // calculate checksums
629 codes.append(checksum(codes, 20)); // "C" checksum
630 codes.append(checksum(codes, 15)); // "K" checksum: includes previous checksum
631
632 // now generate the barcode
633 // the guard sequence that goes on each end
634 const QList<bool> endSequence = sequenceForID(47);
635 barcode += endSequence;
636 // translate codes into bars
637 for (int i = 0; i < codes.size(); i++) {
638 barcode += sequenceForID(codes.at(i));
639 }
640 // ending guard
641 barcode += endSequence;
642 // termination bar
643 barcode += true;
644 }
645
646 const int barWidth = 1;
647 const int quietZoneWidth = 10 * barWidth;
648
649 // build one line of the result image
650 QList<QRgb> line;
651 line.reserve(barWidth * barcode.size() + 2 * quietZoneWidth);
652 line.insert(0, quietZoneWidth, m_background.rgba());
653 for (int i = 0; i < barcode.size(); i++) {
654 const QRgb color = (barcode.at(i) ? m_foreground : m_background).rgba();
655 for (int j = 0; j < barWidth; j++) {
656 line.append(color);
657 }
658 }
659 line.insert(line.size(), quietZoneWidth, m_background.rgba());
660
661 // build the complete barcode
662 QImage ret(line.size(), 1, QImage::Format_ARGB32);
663 memcpy(ret.scanLine(0), line.data(), line.size() * sizeof(QRgb));
664 return ret;
665}
A barcode generator for a fixed barcode format.
Definition barcode.h:40
Provides classes and methods for generating barcodes.
Definition barcode.h:24
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
pointer data()
iterator insert(const_iterator before, parameter_type value)
void reserve(qsizetype size)
qsizetype size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:16:07 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.