summaryrefslogtreecommitdiff
path: root/packaging/designqr.patch
blob: 33f54f5000f1ac6ef0d134ad6e54fe3feb0fe5f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
From 356eae424c638ff24aaf7554b4365f2c9297abaa Mon Sep 17 00:00:00 2001
From: Kwanghoon Son <k.son@samsung.com>
Date: Thu, 12 Jan 2023 15:13:36 +0900
Subject: [PATCH 1/4] Add Design QR definition

Design QR is for various finder, data shape, and color support.

Change-Id: Iaa6a99cb6b38615465130acc71a032d8cb85a9f0
Signed-off-by: Kwanghoon Son <k.son@samsung.com>
---
 backend/raster.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++--
 backend/zint.h   |  4 ++++
 test/test_qr.cpp | 10 ++++++--
 3 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/backend/raster.c b/backend/raster.c
index d609e30..6616f6b 100644
--- a/backend/raster.c
+++ b/backend/raster.c
@@ -604,6 +604,56 @@ void to_latin1(unsigned char source[], unsigned char preprocessed[]) {
     return;
 }
 
+int plot_design_qr(struct zint_symbol *symbol, int rotate_angle, int data_type) {
+    float scaler = 2 * symbol->scale;
+    char *scaled_pixelbuf;
+    int r, i;
+    int scale_width, scale_height;
+    int error_number = 0;
+    int xoffset, yoffset, image_width, image_height;
+
+    symbol->height = symbol->rows; // This is true because only 2d matrix symbols are processed here
+
+    xoffset = symbol->border_width + symbol->whitespace_width;
+    yoffset = symbol->border_width;
+    image_width = symbol->width + xoffset + xoffset;
+    image_height = symbol->height + yoffset + yoffset;
+
+    if (scaler < 2.0) {
+        scaler = 2.0;
+    }
+    scale_width = (image_width * scaler) + 1;
+    scale_height = (image_height * scaler) + 1;
+
+    /* Apply scale options by creating another pixel buffer */
+    if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
+        strcpy(symbol->errtxt, "657: Insufficient memory for pixel buffer");
+        return ZINT_ERROR_ENCODING_PROBLEM;
+    } else {
+        for (i = 0; i < (scale_width * scale_height); i++) {
+            *(scaled_pixelbuf + i) = '0';
+        }
+    }
+
+    /* Plot the body of the symbol to the pixel buffer */
+    for (r = 0; r < symbol->rows; r++) {
+        for (i = 0; i < symbol->width; i++) {
+            if (module_is_set(symbol, r, i)) {
+                draw_circle(scaled_pixelbuf, scale_width, scale_height,
+                        (int) ((i + xoffset) * scaler) + (scaler / 2.0),
+                        (int) ((r + yoffset) * scaler) + (scaler / 2.0),
+                        (symbol->dot_size / 2.0) * scaler,
+                        '1');
+            }
+        }
+    }
+
+    error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type);
+    free(scaled_pixelbuf);
+
+    return error_number;
+}
+
 int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int data_type) {
     float scaler = 2 * symbol->scale;
     char *scaled_pixelbuf;
@@ -1118,6 +1168,12 @@ int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_t
     return error_number;
 }
 
+int is_design_qr(int output_options) {
+    return ( (output_options & BARCODE_DATA_CIRCLE) ||
+    (output_options & BARCODE_FINDER_CIRCLE) ||
+    (output_options & BARCODE_FINDER_ROUNDRECT));
+}
+
 int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type) {
     int error;
 
@@ -1127,8 +1183,8 @@ int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type) {
     }
 #endif /* NO_PNG */
 
-    if (symbol->output_options & BARCODE_DOTTY_MODE) {
-        error = plot_raster_dotty(symbol, rotate_angle, file_type);
+    if (is_design_qr(symbol->output_options)) {
+        error = plot_design_qr(symbol, rotate_angle, file_type);
     } else {
         if (symbol->symbology == BARCODE_MAXICODE) {
             error = plot_raster_maxicode(symbol, rotate_angle, file_type);
diff --git a/backend/zint.h b/backend/zint.h
index fc4e41a..5dd2d11 100644
--- a/backend/zint.h
+++ b/backend/zint.h
@@ -255,6 +255,10 @@ extern "C" {
 #define BARCODE_DOTTY_MODE      256
 #define GS1_GS_SEPARATOR        512
 
+#define BARCODE_DATA_CIRCLE BARCODE_DOTTY_MODE
+#define BARCODE_FINDER_CIRCLE 0x10000
+#define BARCODE_FINDER_ROUNDRECT 0x20000
+
 // Input data types
 #define DATA_MODE	0
 #define UNICODE_MODE	1
diff --git a/test/test_qr.cpp b/test/test_qr.cpp
index 30400de..535b8d8 100644
--- a/test/test_qr.cpp
+++ b/test/test_qr.cpp
@@ -30,8 +30,8 @@
 /* SPDX-License-Identifier: BSD-3-Clause */
 
 #include <gtest/gtest.h>
-#include <zint.h>
 #include <list>
+#include "../backend/zint.h"
 
 /* Returns true (1) if a module is dark/black, otherwise false (0) */
 #define module_is_set(s, y, x) (((s)->encoded_data[(y)][(x) >> 3] >> ((x)&0x07)) & 1)
@@ -3349,6 +3349,7 @@ protected:
 TEST_P(QRcodeEncodeParamTest, test_qr_encode)
 {
     item data = GetParam();
+    std::string test_file = std::string{testing::UnitTest::GetInstance()->current_test_info()->name()} + ".png";
     EXPECT_EQ(1, 1);
     int i, length, ret;
 
@@ -3356,13 +3357,18 @@ TEST_P(QRcodeEncodeParamTest, test_qr_encode)
                                data.option_1, data.option_2, data.option_3, -1 /*output_options*/,
                                data.data, data.length, 0);
 
-    ret = ZBarcode_Encode(symbol, (unsigned char *)data.data, length);
+    ret = ZBarcode_Encode_and_Buffer(symbol, (unsigned char *)data.data, length, 0);
+
+    symbol->output_options |= BARCODE_FINDER_CIRCLE;
+    strcpy(symbol->outfile, test_file.c_str());
 
     // ret is different because it's not supported!
     if (ret != data.ret)
     {
         return;
     };
+
+    ZBarcode_Print(symbol, 0);
 }
 
 INSTANTIATE_TEST_CASE_P(
-- 
2.25.1


From 91094ca139bf9e68fbaa701792b4c6b13f1f5f8e Mon Sep 17 00:00:00 2001
From: Kwanghoon Son <k.son@samsung.com>
Date: Fri, 13 Jan 2023 17:44:43 +0900
Subject: [PATCH 2/4] Add BARCODE_DATA_CIRCLE generator

plot design qr function now handle DATA_CIRCLE

Change-Id: I6f62ce435de51a3d44d5aea5a8f4bfa7fe56e6e9
Signed-off-by: Kwanghoon Son <k.son@samsung.com>
---
 backend/raster.c | 52 ++++++++++++++++++++++++++++++++++++------------
 test/test_qr.cpp |  9 +++++----
 2 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/backend/raster.c b/backend/raster.c
index 6616f6b..343ac5a 100644
--- a/backend/raster.c
+++ b/backend/raster.c
@@ -208,6 +208,17 @@ int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int
     return error_number;
 }
 
+void draw_rect(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height) {
+    /* Draw a rectangle */
+    int i, j;
+
+    for (i = (xpos); i < (xpos + xlen); i++) {
+        for (j = ypos; j < (ypos + ylen); j++) {
+            *(pixelbuf + (image_width * j) + i) = '1';
+        }
+    }
+}
+
 void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height) {
     /* Draw a rectangle */
     int i, j, png_ypos;
@@ -603,9 +614,14 @@ void to_latin1(unsigned char source[], unsigned char preprocessed[]) {
 
     return;
 }
+int is_finder(int x, int y, int w, int h) {
+    return ((x < 7 && y <7) ||
+    (x < 7 && h - y <= 7) ||
+    (w - x <= 7 && y < 7) );
+}
 
 int plot_design_qr(struct zint_symbol *symbol, int rotate_angle, int data_type) {
-    float scaler = 2 * symbol->scale;
+    int scaler = 32;
     char *scaled_pixelbuf;
     int r, i;
     int scale_width, scale_height;
@@ -619,11 +635,8 @@ int plot_design_qr(struct zint_symbol *symbol, int rotate_angle, int data_type)
     image_width = symbol->width + xoffset + xoffset;
     image_height = symbol->height + yoffset + yoffset;
 
-    if (scaler < 2.0) {
-        scaler = 2.0;
-    }
-    scale_width = (image_width * scaler) + 1;
-    scale_height = (image_height * scaler) + 1;
+    scale_width = (image_width * scaler);
+    scale_height = (image_height * scaler);
 
     /* Apply scale options by creating another pixel buffer */
     if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
@@ -638,12 +651,25 @@ int plot_design_qr(struct zint_symbol *symbol, int rotate_angle, int data_type)
     /* Plot the body of the symbol to the pixel buffer */
     for (r = 0; r < symbol->rows; r++) {
         for (i = 0; i < symbol->width; i++) {
-            if (module_is_set(symbol, r, i)) {
-                draw_circle(scaled_pixelbuf, scale_width, scale_height,
-                        (int) ((i + xoffset) * scaler) + (scaler / 2.0),
-                        (int) ((r + yoffset) * scaler) + (scaler / 2.0),
-                        (symbol->dot_size / 2.0) * scaler,
-                        '1');
+            //finder area
+            if (!module_is_set(symbol, r, i)) continue;
+            if(is_finder(r,i, symbol->rows, symbol->width)) {
+                draw_rect(scaled_pixelbuf,(i + xoffset) * scaler, scaler, (r + xoffset) * scaler, scaler, scale_width, scale_height);
+            }
+
+            //data area
+            else {
+                if(symbol->output_options & BARCODE_DATA_CIRCLE) {
+                    draw_circle(scaled_pixelbuf, scale_width, scale_height,
+                            ((i + xoffset) * scaler) + (scaler / 2),
+                            ((r + yoffset) * scaler) + (scaler / 2),
+                            (symbol->dot_size / 2.0) * scaler,
+                            '1');
+                }
+                else {
+                    draw_rect(scaled_pixelbuf,(i + xoffset) * scaler, scaler, (r + xoffset) * scaler, scaler, scale_width, scale_height);
+
+                }
             }
         }
     }
@@ -686,7 +712,7 @@ int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int data_typ
     }
 
     /* Plot the body of the symbol to the pixel buffer */
-    for (r = 0; r < symbol->rows; r++) {
+        for (r = 0; r < symbol->rows; r++) {
         for (i = 0; i < symbol->width; i++) {
             if (module_is_set(symbol, r, i)) {
                 draw_circle(scaled_pixelbuf, scale_width, scale_height,
diff --git a/test/test_qr.cpp b/test/test_qr.cpp
index 535b8d8..05e0637 100644
--- a/test/test_qr.cpp
+++ b/test/test_qr.cpp
@@ -3357,18 +3357,19 @@ TEST_P(QRcodeEncodeParamTest, test_qr_encode)
                                data.option_1, data.option_2, data.option_3, -1 /*output_options*/,
                                data.data, data.length, 0);
 
-    ret = ZBarcode_Encode_and_Buffer(symbol, (unsigned char *)data.data, length, 0);
+    symbol->output_options |= BARCODE_DATA_CIRCLE;
 
-    symbol->output_options |= BARCODE_FINDER_CIRCLE;
     strcpy(symbol->outfile, test_file.c_str());
 
+    // ret = ZBarcode_Encode_and_Buffer(symbol, (unsigned char *)data.data, length, 0);
+    ZBarcode_Encode(symbol, (unsigned char *)data.data, length);
+    ret = ZBarcode_Print(symbol, 0);
+
     // ret is different because it's not supported!
     if (ret != data.ret)
     {
         return;
     };
-
-    ZBarcode_Print(symbol, 0);
 }
 
 INSTANTIATE_TEST_CASE_P(
-- 
2.25.1


From ecf73203efed9b136c9e4eb65fdfa64c85855345 Mon Sep 17 00:00:00 2001
From: Kwanghoon Son <k.son@samsung.com>
Date: Tue, 17 Jan 2023 18:56:49 +0900
Subject: [PATCH 3/4] Add finder pattern

Change-Id: Ia63e2409510deafe8991db91e1ccb2c91c8f1a7c
Signed-off-by: Kwanghoon Son <k.son@samsung.com>
---
 backend/raster.c | 73 +++++++++++++++++++++++++++++++++++-------------
 test/test_qr.cpp |  1 +
 2 files changed, 55 insertions(+), 19 deletions(-)

diff --git a/backend/raster.c b/backend/raster.c
index 343ac5a..56dbb2d 100644
--- a/backend/raster.c
+++ b/backend/raster.c
@@ -208,13 +208,13 @@ int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int
     return error_number;
 }
 
-void draw_rect(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height) {
+void draw_rect(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height, char fill) {
     /* Draw a rectangle */
     int i, j;
 
     for (i = (xpos); i < (xpos + xlen); i++) {
         for (j = ypos; j < (ypos + ylen); j++) {
-            *(pixelbuf + (image_width * j) + i) = '1';
+            *(pixelbuf + (image_width * j) + i) = fill;
         }
     }
 }
@@ -620,6 +620,17 @@ int is_finder(int x, int y, int w, int h) {
     (w - x <= 7 && y < 7) );
 }
 
+void draw_round_rect(char *pixelbuf, int center_x, int center_y, int image_width, int image_height, float radius, int side_len, char fill)
+{
+    for(int w= center_x - side_len/2; w < center_x + side_len/2; w++) {
+        for(int h= center_y - side_len/2; h < center_y + side_len/2; h++) {
+            if(w < 0 || w >= image_width || h < 0 || h >= image_height) continue;
+            float len = (float)(w - center_x) * (float)(w - center_x) + (float)(h - center_y) * (float)(h - center_y);
+            if(len < radius*radius) *(pixelbuf + (image_width * h) + w) = fill;
+        }
+    }
+}
+
 int plot_design_qr(struct zint_symbol *symbol, int rotate_angle, int data_type) {
     int scaler = 32;
     char *scaled_pixelbuf;
@@ -648,28 +659,52 @@ int plot_design_qr(struct zint_symbol *symbol, int rotate_angle, int data_type)
         }
     }
 
+    int cx[3], cy[3];
+    cx[0] = ((3 + xoffset) * scaler) + (scaler / 2);
+    cy[0] = ((3 + yoffset) * scaler) + (scaler / 2);
+
+    cx[1] = (((image_width - 4) - xoffset) * scaler) + (scaler / 2);
+    cy[1] = cy[0];
+
+    cx[2] = cx[0];
+    cy[2] = (((image_height - 4) - yoffset) * scaler) + (scaler / 2);
+
+    if (symbol->output_options & BARCODE_FINDER_CIRCLE)
+    {
+        for(int cc=0; cc < 3; cc++)
+            for(i=3; i>0; i--) {
+            draw_circle(scaled_pixelbuf, scale_width, scale_height, cx[cc], cy[cc], (symbol->dot_size / 2.0) * (i*2 + 1) * scaler, '0' + i%2);
+        }
+
+    } else if (symbol->output_options & BARCODE_FINDER_ROUNDRECT) {
+        for(int cc=0; cc < 3; cc++)
+            for(i=3; i>0; i--) {
+            //0.6 means radius little longer than half of rectangular length
+            draw_round_rect(scaled_pixelbuf, cx[cc], cy[cc], scale_width, scale_height, (i*2 + 1)*scaler*0.6, (i*2 + 1)*scaler, '0' + i%2);
+        }
+    }
+    else {
+        for(int cc=0; cc < 3; cc++)
+            for(i=3; i>0; i--) {
+            draw_round_rect(scaled_pixelbuf, cx[cc], cy[cc], scale_width, scale_height, (i*2 + 1)*scaler*2, (i*2 + 1)*scaler, '0' + i%2);
+        }
+    }
+
     /* Plot the body of the symbol to the pixel buffer */
     for (r = 0; r < symbol->rows; r++) {
         for (i = 0; i < symbol->width; i++) {
-            //finder area
-            if (!module_is_set(symbol, r, i)) continue;
-            if(is_finder(r,i, symbol->rows, symbol->width)) {
-                draw_rect(scaled_pixelbuf,(i + xoffset) * scaler, scaler, (r + xoffset) * scaler, scaler, scale_width, scale_height);
-            }
-
+            //finder area or not set
+            if(is_finder(r,i, symbol->rows, symbol->width) || !module_is_set(symbol, r, i)) continue;
             //data area
+            if(symbol->output_options & BARCODE_DATA_CIRCLE) {
+                draw_circle(scaled_pixelbuf, scale_width, scale_height,
+                        ((i + xoffset) * scaler) + (scaler / 2),
+                        ((r + yoffset) * scaler) + (scaler / 2),
+                        (symbol->dot_size / 2.0) * scaler,
+                        '1');
+            }
             else {
-                if(symbol->output_options & BARCODE_DATA_CIRCLE) {
-                    draw_circle(scaled_pixelbuf, scale_width, scale_height,
-                            ((i + xoffset) * scaler) + (scaler / 2),
-                            ((r + yoffset) * scaler) + (scaler / 2),
-                            (symbol->dot_size / 2.0) * scaler,
-                            '1');
-                }
-                else {
-                    draw_rect(scaled_pixelbuf,(i + xoffset) * scaler, scaler, (r + xoffset) * scaler, scaler, scale_width, scale_height);
-
-                }
+                draw_rect(scaled_pixelbuf,(i + xoffset) * scaler, scaler, (r + xoffset) * scaler, scaler, scale_width, scale_height, '1');
             }
         }
     }
diff --git a/test/test_qr.cpp b/test/test_qr.cpp
index 05e0637..cfd1060 100644
--- a/test/test_qr.cpp
+++ b/test/test_qr.cpp
@@ -3358,6 +3358,7 @@ TEST_P(QRcodeEncodeParamTest, test_qr_encode)
                                data.data, data.length, 0);
 
     symbol->output_options |= BARCODE_DATA_CIRCLE;
+    symbol->output_options |= BARCODE_FINDER_ROUNDRECT;
 
     strcpy(symbol->outfile, test_file.c_str());
 
-- 
2.25.1


From 3d780674174e5f7d9772964071ddead07ff06a98 Mon Sep 17 00:00:00 2001
From: Kwanghoon Son <k.son@samsung.com>
Date: Wed, 18 Jan 2023 11:29:35 +0900
Subject: [PATCH 4/4] Fix draw_circle radius to 0.45 in finder

Reader works over than 0.45

Change-Id: Ifb9ffda6776c5c40411373c04a70e3a13d8d8086
Signed-off-by: Kwanghoon Son <k.son@samsung.com>
---
 backend/raster.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/backend/raster.c b/backend/raster.c
index 56dbb2d..25a055b 100644
--- a/backend/raster.c
+++ b/backend/raster.c
@@ -673,7 +673,8 @@ int plot_design_qr(struct zint_symbol *symbol, int rotate_angle, int data_type)
     {
         for(int cc=0; cc < 3; cc++)
             for(i=3; i>0; i--) {
-            draw_circle(scaled_pixelbuf, scale_width, scale_height, cx[cc], cy[cc], (symbol->dot_size / 2.0) * (i*2 + 1) * scaler, '0' + i%2);
+            //less than 0.45 will not works well in reader
+            draw_circle(scaled_pixelbuf, scale_width, scale_height, cx[cc], cy[cc], 0.45 * (i*2 + 1) * scaler, '0' + i%2);
         }
 
     } else if (symbol->output_options & BARCODE_FINDER_ROUNDRECT) {
-- 
2.25.1