commit 6b39e0b9d3c3e27110a6f3b5986e3a58b221c38b
parent a0664a80213bcf5731c7ddf39d38f47171622960
Author: TheJackiMonster <thejackimonster@gmail.com>
Date: Wed, 17 Nov 2021 01:05:24 +0100
Implemented QR decoding using zbar_image_scanner
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat:
2 files changed, 91 insertions(+), 27 deletions(-)
diff --git a/resources/ui/new_contact.ui b/resources/ui/new_contact.ui
@@ -73,11 +73,7 @@ Author: Tobias Frisch
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="halign">center</property>
- <property name="margin-start">8</property>
- <property name="margin-end">8</property>
- <property name="margin-top">8</property>
- <property name="margin-bottom">8</property>
+ <property name="border-width">8</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
@@ -120,7 +116,7 @@ Author: Tobias Frisch
</child>
</object>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
diff --git a/src/ui/new_contact.c b/src/ui/new_contact.c
@@ -68,26 +68,43 @@ handle_id_drawing_area_draw(GtkWidget* drawing_area,
GdkPixbuf *image = NULL;
- if (handle->image)
- {
- uint w, h;
- zbar_image_get_size(handle->image, &w, &h);
-
- const void* data = zbar_image_get_data(handle->image);
-
- image = gdk_pixbuf_new_from_data(
- data,
- GDK_COLORSPACE_RGB,
- FALSE,
- 8,
- w,
- h,
- w * 3,
- NULL,
- NULL
- );
- }
+ if (!handle->image)
+ goto render_image;
+
+ uint w, h;
+ zbar_image_get_size(handle->image, &w, &h);
+
+ uint x, y, min_size;
+ min_size = (w < h? w : h);
+ x = (w - min_size) / 2;
+ y = (h - min_size) / 2;
+
+ const void* data = (const void*) (
+ (const char*) zbar_image_get_data(handle->image) +
+ (x + y * w) * 3
+ );
+
+ image = gdk_pixbuf_new_from_data(
+ data,
+ GDK_COLORSPACE_RGB,
+ FALSE,
+ 8,
+ min_size,
+ min_size,
+ w * 3,
+ NULL,
+ NULL
+ );
+ GString *scan_result = (GString*) zbar_image_get_userdata(handle->image);
+
+ if (!scan_result)
+ goto render_image;
+
+ gtk_entry_set_text(handle->id_entry, scan_result->str);
+ g_string_free(scan_result, TRUE);
+
+render_image:
if (!image)
return FALSE;
@@ -143,6 +160,43 @@ idle_video_processing(gpointer user_data)
if (!image)
return TRUE;
+ GString *scan_result = NULL;
+
+ zbar_image_t *y8 = zbar_image_convert(
+ image,
+ zbar_fourcc('Y', '8', '0', '0')
+ );
+
+ if (zbar_scan_image(handle->scanner, y8) <= 0)
+ goto cleanup_scan;
+
+ const zbar_symbol_set_t* set = zbar_image_scanner_get_results(
+ handle->scanner
+ );
+
+ const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(set);
+
+ if (!symbol)
+ goto cleanup_scan;
+
+ uint data_len = 0;
+ const char *data = NULL;
+
+ for (; symbol; symbol = zbar_symbol_next(symbol))
+ {
+ if (zbar_symbol_get_count(symbol))
+ continue;
+
+ data_len = zbar_symbol_get_data_length(symbol);
+ data = zbar_symbol_get_data(symbol);
+ }
+
+ if ((data_len > 0) && (data))
+ scan_result = g_string_new_len(data, data_len);
+
+cleanup_scan:
+ zbar_image_destroy(y8);
+
zbar_image_t *rgb = zbar_image_convert(
image,
zbar_fourcc('R', 'G', 'B', '3')
@@ -151,6 +205,8 @@ idle_video_processing(gpointer user_data)
if (!rgb)
goto cleanup_image;
+ zbar_image_set_userdata(rgb, scan_result);
+
if (handle->image)
zbar_image_destroy(handle->image);
@@ -169,12 +225,19 @@ _ui_new_contact_video_thread(void *args)
{
UI_NEW_CONTACT_Handle *handle = (UI_NEW_CONTACT_Handle*) args;
- if (0 != zbar_video_open(handle->video, "/dev/video0"))
+ if (0 != zbar_video_open(handle->video, ""))
return NULL;
if (0 != zbar_video_enable(handle->video, 1))
return NULL;
+ zbar_image_scanner_set_config(
+ handle->scanner,
+ ZBAR_QRCODE,
+ ZBAR_CFG_ENABLE,
+ TRUE
+ );
+
handle->idle_processing = g_idle_add(idle_video_processing, handle);
return NULL;
}
@@ -216,7 +279,7 @@ ui_new_contact_dialog_init(MESSENGER_Application *app,
);
handle->id_entry = GTK_ENTRY(
- gtk_builder_get_object(handle->builder, "platform_entry")
+ gtk_builder_get_object(handle->builder, "id_entry")
);
handle->cancel_button = GTK_BUTTON(
@@ -263,6 +326,11 @@ ui_new_contact_dialog_cleanup(UI_NEW_CONTACT_Handle *handle)
g_object_unref(handle->builder);
+ if (handle->image)
+ zbar_image_destroy(handle->image);
+
+ handle->image = NULL;
+
zbar_image_scanner_destroy(handle->scanner);
zbar_video_destroy(handle->video);
}