Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8585 rgimad 1
/* Copyright (C) 2021- Rustem Gimadutdinov (rgimad), GPLv2 */
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
 
8
#include "kolibri_gui.h"
9
#include "kolibri_opendialog.h"
10
#include "kolibri_libimg.h"
11
 
12
#include "quirc.h"
13
 
14
/* ------------------------------------------------------- */
15
 
16
#define X_W(X, W) ((X<<16)+W)
17
#define Y_H X_W
18
 
19
#define WINDOW_WIDTH 650
20
#define WINDOW_HEIGHT 320
21
 
22
#define WINDOW_ROW1_Y 34
23
#define WINDOW_COL2_X 280
24
 
25
#define TEDIT1_MAXCHAR 2048
26
#define TEDIT1_W 340
27
#define TEDIT1_H 150
28
 
29
#define IMG1_DISPLAY_W 256
30
#define IMG1_DISPLAY_H 256
31
 
32
const char WINDOW_TITLE[] = "QR Tool 0.2b";
33
 
34
kolibri_system_colors sys_color_table;
35
const color_t DRAWTEXT_FLAG_DEFAULT = 0x90000000;
36
 
37
enum MYCOLORS {
38
    COL_GREEN = 0x067D06,
39
    COL_BLUE  = 0x0000FF,
40
    COL_RED   = 0xFF0000,
41
    COL_BLACK = 0x000000,
42
    COL_WHITE = 0xFFFFFF,
43
    COL_GREY  = 0x919191
44
};
45
 
46
enum MYBUTTONS {
47
    MYBTN_QUIT = 1,
48
    MYBTN_OPEN = 10/*,
49
    MYBTN_CLEAR = 20*/
50
    //
51
};
52
 
53
editor *tedit1;
54
void *tedit1_lock;
55
 
56
open_dialog *op_dialog1;
57
 
58
Image *img1 = NULL;
59
Image *img1_grayscale = NULL;
60
char *img1_path;
61
 
62
char cur_dir_path[256];
63
 
64
 
65
char* load_img(char* fname, uint32_t* read_sz) {
66
    FILE *f = fopen(fname, "rb");
67
    if (!f) {
68
        printf("Can't open file: %s\n", fname);
69
        exit(0);
70
    }
71
    if (fseek(f, 0, SEEK_END)) {
72
        printf("Can't SEEK_END file: %s\n", fname);
73
        exit(0);
74
    }
75
    int filesize = ftell(f);
76
    rewind(f);
77
    char* fdata = malloc(filesize);
78
    if(!fdata) {
79
        printf("No memory for file %s\n", fname);
80
        exit(0);
81
    }
82
    *read_sz = fread(fdata, 1, filesize, f);
83
    if (ferror(f)) {
84
        printf("Error reading file %s\n", fname);
85
        exit(0);
86
    }
87
    fclose(f);
88
    return fdata;
89
}
90
 
91
/* mode: 0 - ASCII, 1 - SCAN*/
92
void set_os_keyb_mode(int mode) { __asm__ __volatile__("int $0x40"::"a"(66), "b"(1), "c"(mode)); }
93
 
94
void redraw_window() {
95
    pos_t win_pos = get_mouse_pos(0);
96
    begin_draw();
97
    sys_create_window(win_pos.x, win_pos.y, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, sys_color_table.color_work_area, 0x14);
98
 
99
    //draw_text_sys("", /*x*/, /*y*/, 0, DRAWTEXT_FLAG_DEFAULT | sys_color_table.work_text);
100
 
101
    define_button(X_W(WINDOW_COL2_X,100), Y_H(WINDOW_ROW1_Y,30), MYBTN_OPEN, sys_color_table.color_work_button);
102
    draw_text_sys("Open image", WINDOW_COL2_X + 12, WINDOW_ROW1_Y + 7, 0, DRAWTEXT_FLAG_DEFAULT | sys_color_table.color_work_button_text);
103
 
104
    //define_button(X_W(WINDOW_COL2_X + 120,100), Y_H(WINDOW_ROW1_Y,30), MYBTN_CLEAR, sys_color_table.color_work_button);
105
 
106
    draw_text_sys("Recognition results below.", WINDOW_COL2_X, WINDOW_ROW1_Y + 40, 0, DRAWTEXT_FLAG_DEFAULT | sys_color_table.color_work_text);
107
    draw_text_sys("Selection & Ctrl+C available.", WINDOW_COL2_X, WINDOW_ROW1_Y + 60, 0, DRAWTEXT_FLAG_DEFAULT | sys_color_table.color_work_text);
108
 
109
    ted_draw(tedit1);
110
 
111
    if (img1 != NULL) {
112
        //printf("drawing...\n");
113
        img_draw(img1, 10, WINDOW_ROW1_Y, IMG1_DISPLAY_W, IMG1_DISPLAY_H , 0, 0);
114
    } else {
115
        draw_bar(10, WINDOW_ROW1_Y, IMG1_DISPLAY_W, IMG1_DISPLAY_H, COL_GREY);
116
    }
117
 
118
    end_draw();
119
}
120
 
121
void tedit1_print(const char *text, int text_len, int do_newline) {
122
    if (text_len == -1) { text_len = strlen(text); }
123
    ted_text_add(tedit1, (char *)text, text_len, 1);
124
    if (do_newline != 0 ) { ted_text_add(tedit1, "\r", 1, 1); }
125
}
126
 
127
void create_components() {
128
    tedit1 = kolibri_new_editor(X_W(WINDOW_COL2_X, TEDIT1_W), Y_H(WINDOW_ROW1_Y + IMG1_DISPLAY_H - TEDIT1_H - 16, TEDIT1_H), 0/*0x11*/, TEDIT1_MAXCHAR, &tedit1_lock);  // 0x11 font 8x16 sized x2, 0 - default (8x16)
129
    tedit1_lock = tedit1;
130
    tedit1->mode_invis = 0; /* dont show invisible characters */
131
 
132
    op_dialog1 = kolibri_new_open_dialog(OPEN, 10, 10, 420, 320);
133
    op_dialog1->dir_default_path = cur_dir_path;
134
    op_dialog1->draw_window = redraw_window;
135
    OpenDialog_init(op_dialog1);
136
}
137
 
138
void recognize_qr() {
139
    puts("Starting QUIRC...\n");
140
    struct quirc *qr;
141
 
142
    qr = quirc_new();
143
    if (!qr) {
144
        puts("Failed to allocate memory");
145
        exit(-1);
146
    }
147
 
148
    if (quirc_resize(qr, img1_grayscale->Width, img1_grayscale->Height) < 0) {
149
        puts("Failed to allocate video memory");
150
        exit(-1);
151
    }
152
 
153
    void *gsbuf = img1_grayscale->Data;
154
    uint32_t gsbuf_size = img1_grayscale->Width*img1_grayscale->Height;
155
 
156
    uint8_t *buffer;
157
    int w, h;
158
    puts("quirc_begin()...\n");
159
    buffer = quirc_begin(qr, &w, &h);
160
    //printf("buffer = %x  qr = %x\n", buffer, qr);
161
    //printf("w = %d   h = %d\n", w, h);
162
    memcpy(buffer, gsbuf, gsbuf_size);
163
    puts("quirc_end()...\n");
164
    quirc_end(qr);
165
 
166
    ted_clear(tedit1, 1); /* cleaning output text area */
167
 
168
    int num_codes, i;
169
    puts("quirc_count()...\n");
170
    num_codes = quirc_count(qr);
171
    printf("    NUM_CODES = %d\n", num_codes);
172
    if (num_codes == 0) {
173
        tedit1_print("DECODE FAILED: NO CODES FOUND", -1, 1);
174
    }
175
    for (i = 0; i < num_codes; i++) {
176
        struct quirc_code code;
177
        struct quirc_data data;
178
        quirc_decode_error_t err;
179
 
180
        quirc_extract(qr, i, &code);
181
 
182
        // decoding stage
183
        err = quirc_decode(&code, &data);
184
        if (err) {
185
            //printf("    DECODE FAILED: %s\n", quirc_strerror(err));
186
            tedit1_print("DECODE FAILED: ", -1, 0);
187
            tedit1_print(quirc_strerror(err), -1, 1);
188
        } else {
189
            //printf("\n    RECOGNIZED DATA: %s\n", data.payload);
190
            tedit1_print("RECOGNIZED: ", -1, 0);
191
            tedit1_print(data.payload, data.payload_len, 1);
192
        }
193
    }
194
 
195
    puts("\nquirc_destroy()...\n");
196
    quirc_destroy(qr);
197
}
198
 
199
void on_btn_open() {
200
    //ted_text_add(tedit1, "Hello world!\r", strlen("Hello world!\r"), 1);
201
    op_dialog1->mode = OPEN;
202
    OpenDialog_start(op_dialog1);
203
    if (op_dialog1->status != 2 && op_dialog1->status != 0) {// fail or cancel
204
        img1_path = op_dialog1->openfile_path;
205
        //ted_text_add(tedit1, img1_path, strlen(img1_path), 1);
206
        //ted_text_add(tedit1, "\r", 1, 1); // newline
207
    } else {
208
        return;
209
    }
210
    Image *oldimg;
211
    if (img1 != NULL) { img_destroy(img1); }
212
    if (img1_grayscale != NULL) { img_destroy(img1_grayscale); }
213
    uint32_t file_size;
214
    void *file_data = load_img(img1_path, &file_size); // Get RAW data and size
215
    img1 = img_decode(file_data, file_size, 0); // Decode RAW data to Image data
216
    img1_grayscale = img_decode(file_data, file_size, 0); // Decode RAW data to Image data
217
    free(file_data); //
218
    printf("original: image->Width = %d, Image->Height = %d,\n original image type = %d\n\n", img1->Width, img1->Height, img1->Type);
219
    if (img1->Type != IMAGE_BPP24) {
220
        oldimg = img1; //
221
        img1 = img_convert(img1, NULL, IMAGE_BPP24, 0, 0); // Convert image to RGB 24
222
        img_destroy(oldimg); //
223
        if (!img1) {
224
            printf("Сonvert img1 to BPP24 error!: \n");
225
            exit(-1);
226
        }
227
    }
228
    if (img1_grayscale->Type != IMAGE_BPP24) {
229
        oldimg = img1_grayscale; //
230
        img1_grayscale = img_convert(img1_grayscale, NULL, IMAGE_BPP24, 0, 0); // Convert image to RGB
231
        img_destroy(oldimg); //
232
        if (!img1_grayscale) {
233
            printf("Сonvert img1_grayscale to BPP24 error!: \n");
234
            exit(-1);
235
        }
236
    }
237
    if (img1_grayscale->Type != IMAGE_BPP8g) {
238
        oldimg = img1_grayscale; //
239
        img1_grayscale = img_convert(img1_grayscale, NULL, IMAGE_BPP8g, 0, 0); // Convert image to grayscale
240
        img_destroy(oldimg); //
241
        if (!img1_grayscale) {
242
            printf("Сonvert img1_grayscale to BPP8g error!: \n");
243
            exit(-1);
244
        }
245
    }
246
    oldimg = img1; //
247
    img1 = img_scale(img1, 0, 0, img1->Width, img1->Height, NULL, LIBIMG_SCALE_STRETCH , LIBIMG_INTER_BILINEAR, IMG1_DISPLAY_W, IMG1_DISPLAY_H);
248
    img_destroy(oldimg); //
249
 
250
    recognize_qr();
251
}
252
 
253
int main(int argc, char *argv[]) {
254
    int gui_event; /* variable for storing event */
255
    uint32_t pressed_button = 0; /* code of button pressed in window */
256
    unsigned int keyval; /* for saving pressed key */
257
    oskey_t key;
258
 
259
    ((void)argc);
260
    strcpy(cur_dir_path, argv[0] + 2); char *pc = strrchr(cur_dir_path, '/'); if (pc) { *pc = '\0'; }
261
    printf("cur_dir_path = %s\n", cur_dir_path);
262
 
263
    kolibri_boxlib_init();
264
    kolibri_proclib_init();  // opensave && color dialogs
265
    kolibri_libimg_init();
266
 
267
    set_wanted_events_mask(0xC0000027);
268
    set_os_keyb_mode(1); // scan code mode needed for editor
269
 
270
    kolibri_get_system_colors(&sys_color_table); // Get system colors theme
271
 
272
    create_components();
273
 
274
    do {
275
        gui_event = get_os_event();
276
        switch(gui_event) {
277
        case KOLIBRI_EVENT_NONE:
278
            break;
279
        case KOLIBRI_EVENT_REDRAW:
280
            redraw_window();
281
            break;
282
        case KOLIBRI_EVENT_MOUSE:
283
            ted_mouse(tedit1);
284
            break;
285
        case KOLIBRI_EVENT_KEY:
286
            key = get_key();
287
            if (tedit1_lock == tedit1) { editor_key(tedit1, key); }
288
            break;
289
        case KOLIBRI_EVENT_BUTTON:
290
            pressed_button = get_os_button();
291
            switch (pressed_button)
292
            {
293
                case MYBTN_OPEN:
294
                {
295
                    on_btn_open();
296
                    redraw_window();
297
                    break;
298
                }
299
 
300
                /*case MYBTN_CLEAR:
301
                    ted_clear(tedit1, 1);
302
                    redraw_window();
303
                    break; */
304
 
305
                case MYBTN_QUIT:
306
                    exit(0);
307
                    break;
308
            }
309
        }
310
    } while (1);
311
 
312
    exit(0);
313
}