Pharos 0.7.23
Modern Web Framework & Web App Hosting Service.
Loading...
Searching...
No Matches
pharos_zxing_reader.c
Go to the documentation of this file.
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#if defined(__has_include)
8# if __has_include(<ZXing/ZXingC.h>)
9# if defined(__clang__)
10# pragma clang diagnostic push
11# pragma clang diagnostic ignored "-Wunused-but-set-variable"
12# pragma clang diagnostic ignored "-Wunused-variable"
13# endif
14# include <ZXing/ZXingC.h>
15# if defined(__clang__)
16# pragma clang diagnostic pop
17# endif
18# else
19typedef struct ZXing_ImageView ZXing_ImageView;
20typedef struct ZXing_ReaderOptions ZXing_ReaderOptions;
21typedef struct ZXing_Barcodes ZXing_Barcodes;
22typedef struct ZXing_Barcode ZXing_Barcode;
23typedef enum {
24 ZXing_ImageFormat_Lum = 0
25} ZXing_ImageFormat;
26typedef enum {
27 ZXing_BarcodeFormat_QRCode = 0
28} ZXing_BarcodeFormat;
29ZXing_ImageView *ZXing_ImageView_new(const unsigned char *data, int width, int height, ZXing_ImageFormat format, int rowStride, int pixStride);
30void ZXing_ImageView_delete(ZXing_ImageView *imageView);
31ZXing_ReaderOptions *ZXing_ReaderOptions_new(void);
32void ZXing_ReaderOptions_delete(ZXing_ReaderOptions *opts);
33void ZXing_ReaderOptions_setFormats(ZXing_ReaderOptions *opts, const ZXing_BarcodeFormat *formats, int count);
34ZXing_Barcodes *ZXing_ReadBarcodes(const ZXing_ImageView *image, const ZXing_ReaderOptions *opts);
35int ZXing_Barcodes_size(const ZXing_Barcodes *barcodes);
36const ZXing_Barcode *ZXing_Barcodes_at(const ZXing_Barcodes *barcodes, int index);
37char *ZXing_Barcode_text(const ZXing_Barcode *barcode);
38void ZXing_Barcodes_delete(ZXing_Barcodes *barcodes);
39void ZXing_free(void *ptr);
40# endif
41#else
42# if defined(__clang__)
43# pragma clang diagnostic push
44# pragma clang diagnostic ignored "-Wunused-but-set-variable"
45# pragma clang diagnostic ignored "-Wunused-variable"
46# endif
47# include <ZXing/ZXingC.h>
48# if defined(__clang__)
49# pragma clang diagnostic pop
50# endif
51#endif
52
53#define STB_IMAGE_IMPLEMENTATION
54#define STBI_NO_LINEAR
55#define STBI_NO_HDR
56#include "stb_image.h"
57
58static int pharos_zxing_copy_text(const char *source_text, char **decoded_text_out) {
59 char *copied_text = NULL;
60 size_t text_length = 0;
61
62 if (decoded_text_out == NULL) {
63 return 64;
64 }
65 *decoded_text_out = NULL;
66 if (source_text == NULL || source_text[0] == '\0') {
67 return 1;
68 }
69
70 text_length = strlen(source_text);
71 copied_text = (char *)malloc(text_length + 1);
72 if (copied_text == NULL) {
73 return 69;
74 }
75 memcpy(copied_text, source_text, text_length + 1);
76 *decoded_text_out = copied_text;
77 return 0;
78}
79
80int pharos_zxing_decode_image_path(const char *image_path, char **decoded_text_out) {
81 ZXing_ImageView *image_view = NULL;
82 ZXing_ReaderOptions *options = NULL;
83 ZXing_Barcodes *barcodes = NULL;
84 const ZXing_Barcode *barcode = NULL;
85 char *zxing_text = NULL;
86 stbi_uc *pixels = NULL;
87 ZXing_BarcodeFormat formats[] = {ZXing_BarcodeFormat_QRCode};
88 int width = 0;
89 int height = 0;
90 int channels = 0;
91 int exit_code = 1;
92
93 if (decoded_text_out == NULL) {
94 return 64;
95 }
96 *decoded_text_out = NULL;
97
98 if (image_path == NULL || image_path[0] == '\0') {
99 return 64;
100 }
101
102 pixels = stbi_load(image_path, &width, &height, &channels, STBI_grey);
103 if (pixels == NULL || width <= 0 || height <= 0) {
104 goto cleanup;
105 }
106
107 image_view = ZXing_ImageView_new(pixels, width, height, ZXing_ImageFormat_Lum, 0, 0);
108 if (image_view == NULL) {
109 goto cleanup;
110 }
111
112 options = ZXing_ReaderOptions_new();
113 if (options == NULL) {
114 exit_code = 69;
115 goto cleanup;
116 }
117
118 ZXing_ReaderOptions_setFormats(options, formats, 1);
119 barcodes = ZXing_ReadBarcodes(image_view, options);
120 if (barcodes == NULL || ZXing_Barcodes_size(barcodes) <= 0) {
121 goto cleanup;
122 }
123
124 barcode = ZXing_Barcodes_at(barcodes, 0);
125 if (barcode == NULL) {
126 goto cleanup;
127 }
128
129 zxing_text = ZXing_Barcode_text(barcode);
130 exit_code = pharos_zxing_copy_text(zxing_text, decoded_text_out);
131
132cleanup:
133 if (zxing_text != NULL) {
134 ZXing_free(zxing_text);
135 }
136 if (barcodes != NULL) {
137 ZXing_Barcodes_delete(barcodes);
138 }
139 if (options != NULL) {
140 ZXing_ReaderOptions_delete(options);
141 }
142 if (image_view != NULL) {
143 ZXing_ImageView_delete(image_view);
144 }
145 if (pixels != NULL) {
146 stbi_image_free(pixels);
147 }
148
149 return exit_code;
150}
151
152int pharos_zxing_reader_main(int argc, char **argv) {
153 char *decoded_text = NULL;
154 int exit_code = 0;
155
156 if (argc != 2) {
157 fprintf(stderr, "usage: %s IMAGE_PATH\n", argc > 0 ? argv[0] : "pharos-zxing-reader");
158 return 64;
159 }
160
161 exit_code = pharos_zxing_decode_image_path(argv[1], &decoded_text);
162 if (exit_code == 0 && decoded_text != NULL) {
163 printf("%s", decoded_text);
164 }
165 free(decoded_text);
166 return exit_code;
167}
static int pharos_zxing_copy_text(const char *source_text, char **decoded_text_out)
int pharos_zxing_reader_main(int argc, char **argv)
int pharos_zxing_decode_image_path(const char *image_path, char **decoded_text_out)
unsigned char stbi_uc
Definition stb_image.h:387
@ STBI_grey
Definition stb_image.h:380
STBIDEF void stbi_image_free(void *retval_from_stbi_load)
STBIDEF stbi_uc * stbi_load(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels)
const char * ptr
Definition yyjson.h:8356