Add clang-format as part of CI
This commit is contained in:
parent
e78bd99305
commit
a92104e27c
|
@ -7,12 +7,18 @@
|
|||
build:debian:
|
||||
image: debian:bookworm-slim
|
||||
before_script:
|
||||
- apt update && apt -y install gcc meson ninja-build libgtk-4-dev libtiff-dev libzbar-dev
|
||||
<<: *build_definition
|
||||
- apt update && apt -y install gcc meson ninja-build clang-format-12 libgtk-4-dev libtiff-dev libzbar-dev
|
||||
script:
|
||||
- meson build
|
||||
- ninja -C build
|
||||
- ninja -C build test
|
||||
- ninja -C build clang-format-check
|
||||
|
||||
build:alpine:
|
||||
image: alpine:edge
|
||||
before_script:
|
||||
- apk add --no-cache build-base meson samurai gtk4.0-dev tiff-dev zbar-dev
|
||||
<<: *build_definition
|
||||
|
||||
script:
|
||||
- meson build
|
||||
- ninja -C build
|
||||
- ninja -C build test
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd "$MESON_SOURCE_ROOT"
|
||||
clang-format-12 $@
|
|
@ -6,6 +6,8 @@ uniform sampler2D texture;
|
|||
|
||||
varying vec2 uv;
|
||||
|
||||
void main() {
|
||||
void
|
||||
main()
|
||||
{
|
||||
gl_FragColor = vec4(texture2D(texture, uv).rgb, 1);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ uniform mat3 transform;
|
|||
|
||||
varying vec2 uv;
|
||||
|
||||
void main() {
|
||||
void
|
||||
main()
|
||||
{
|
||||
uv = tex_coord;
|
||||
|
||||
gl_Position = vec4(transform * vec3(vert, 1), 1);
|
||||
|
|
|
@ -10,15 +10,16 @@ varying vec2 top_right_uv;
|
|||
varying vec2 bottom_left_uv;
|
||||
varying vec2 bottom_right_uv;
|
||||
|
||||
void main() {
|
||||
void
|
||||
main()
|
||||
{
|
||||
// Note the coordinates for texture samples need to be a varying, as the
|
||||
// Mali-400 has this as a fast path allowing 32-bit floats. Otherwise
|
||||
// they end up as 16-bit floats and that's not accurate enough.
|
||||
vec4 samples = vec4(
|
||||
texture2D(texture, top_left_uv).r,
|
||||
texture2D(texture, top_right_uv).r,
|
||||
texture2D(texture, bottom_left_uv).r,
|
||||
texture2D(texture, bottom_right_uv).r);
|
||||
vec4 samples = vec4(texture2D(texture, top_left_uv).r,
|
||||
texture2D(texture, top_right_uv).r,
|
||||
texture2D(texture, bottom_left_uv).r,
|
||||
texture2D(texture, bottom_right_uv).r);
|
||||
|
||||
// Assume BGGR for now. Currently this just takes 3 of the four samples
|
||||
// for each pixel, there's room here to do some better debayering.
|
||||
|
@ -31,7 +32,8 @@ void main() {
|
|||
//vec3 corrected = color_matrix * color2;
|
||||
|
||||
// Fast SRGB estimate. See https://mimosa-pudica.net/fast-gamma/
|
||||
vec3 srgb_color = (vec3(1.138) * inversesqrt(corrected) - vec3(0.138)) * corrected;
|
||||
vec3 srgb_color =
|
||||
(vec3(1.138) * inversesqrt(corrected) - vec3(0.138)) * corrected;
|
||||
|
||||
// Slow SRGB estimate
|
||||
// vec3 srgb_color = pow(color, vec3(1.0 / 2.2));
|
||||
|
|
|
@ -13,7 +13,9 @@ varying vec2 top_right_uv;
|
|||
varying vec2 bottom_left_uv;
|
||||
varying vec2 bottom_right_uv;
|
||||
|
||||
void main() {
|
||||
void
|
||||
main()
|
||||
{
|
||||
top_left_uv = tex_coord - pixel_size / 2.0;
|
||||
bottom_right_uv = tex_coord + pixel_size / 2.0;
|
||||
top_right_uv = vec2(top_left_uv.x, bottom_right_uv.y);
|
||||
|
|
|
@ -4,6 +4,8 @@ precision mediump float;
|
|||
|
||||
uniform vec4 color;
|
||||
|
||||
void main() {
|
||||
void
|
||||
main()
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ precision mediump float;
|
|||
|
||||
attribute vec2 vert;
|
||||
|
||||
void main() {
|
||||
void
|
||||
main()
|
||||
{
|
||||
gl_Position = vec4(vert, 0, 1);
|
||||
}
|
||||
|
|
43
meson.build
43
meson.build
|
@ -77,3 +77,46 @@ executable('megapixels-camera-test',
|
|||
include_directories: 'src/',
|
||||
dependencies: [gtkdep],
|
||||
install: true)
|
||||
|
||||
# Formatting
|
||||
clang_format = find_program('clang-format-12', required: false)
|
||||
if clang_format.found()
|
||||
format_files = [
|
||||
'data/blit.frag',
|
||||
'data/blit.vert',
|
||||
'data/debayer.frag',
|
||||
'data/debayer.vert',
|
||||
'data/solid.frag',
|
||||
'data/solid.vert',
|
||||
'src/camera.c',
|
||||
'src/camera.h',
|
||||
'src/camera_config.c',
|
||||
'src/camera_config.h',
|
||||
'src/device.c',
|
||||
'src/device.h',
|
||||
'src/flash.c',
|
||||
'src/flash.h',
|
||||
'src/gl_util.c',
|
||||
'src/gl_util.h',
|
||||
'src/gles2_debayer.c',
|
||||
'src/gles2_debayer.h',
|
||||
'src/io_pipeline.c',
|
||||
'src/io_pipeline.h',
|
||||
'src/main.c',
|
||||
'src/main.h',
|
||||
'src/matrix.c',
|
||||
'src/matrix.h',
|
||||
'src/pipeline.c',
|
||||
'src/pipeline.h',
|
||||
'src/process_pipeline.c',
|
||||
'src/process_pipeline.h',
|
||||
'src/zbar_pipeline.c',
|
||||
'src/zbar_pipeline.h',
|
||||
'tools/camera_test.c',
|
||||
'tools/list_devices.c',
|
||||
]
|
||||
run_target('clang-format',
|
||||
command: ['clang-format.sh', '-i'] + format_files)
|
||||
run_target('clang-format-check',
|
||||
command: ['clang-format.sh', '-n', '-Werror'] + format_files)
|
||||
endif
|
||||
|
|
|
@ -277,7 +277,8 @@ mp_camera_new(int video_fd, int subdev_fd)
|
|||
camera->has_set_mode = false;
|
||||
camera->num_buffers = 0;
|
||||
camera->use_mplane = use_mplane;
|
||||
memset(camera->child_bg_pids, 0, sizeof(camera->child_bg_pids[0]) * MAX_BG_TASKS);
|
||||
memset(camera->child_bg_pids, 0,
|
||||
sizeof(camera->child_bg_pids[0]) * MAX_BG_TASKS);
|
||||
return camera;
|
||||
}
|
||||
|
||||
|
@ -305,7 +306,8 @@ mp_camera_add_bg_task(MPCamera *camera, pid_t pid)
|
|||
return;
|
||||
} else {
|
||||
// error == -1, still running == 0
|
||||
if (waitpid(camera->child_bg_pids[i], &status, WNOHANG) <= 0)
|
||||
if (waitpid(camera->child_bg_pids[i], &status,
|
||||
WNOHANG) <= 0)
|
||||
continue; // consider errored wait still running
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
|
@ -741,7 +743,8 @@ mp_camera_capture_buffer(MPCamera *camera, MPBuffer *buffer)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool mp_camera_release_buffer(MPCamera *camera, uint32_t buffer_index)
|
||||
bool
|
||||
mp_camera_release_buffer(MPCamera *camera, uint32_t buffer_index)
|
||||
{
|
||||
struct v4l2_buffer buf = {};
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
|
|
@ -37,8 +37,8 @@ find_config(char *conffile)
|
|||
}
|
||||
|
||||
// Check for a config file in XDG_CONFIG_HOME
|
||||
sprintf(conffile, "%s/megapixels/config/%s.ini", g_get_user_config_dir (),
|
||||
buf);
|
||||
sprintf(conffile, "%s/megapixels/config/%s.ini",
|
||||
g_get_user_config_dir(), buf);
|
||||
if (access(conffile, F_OK) != -1) {
|
||||
printf("Found config file at %s\n", conffile);
|
||||
return true;
|
||||
|
|
113
src/flash.c
113
src/flash.c
|
@ -29,7 +29,7 @@ struct _MPFlash {
|
|||
};
|
||||
|
||||
MPFlash *
|
||||
mp_led_flash_from_path(const char * path)
|
||||
mp_led_flash_from_path(const char *path)
|
||||
{
|
||||
MPFlash *flash = malloc(sizeof(MPFlash));
|
||||
flash->type = FLASH_TYPE_LED;
|
||||
|
@ -52,28 +52,27 @@ static GtkWidget *flash_window = NULL;
|
|||
static GDBusProxy *dbus_brightness_proxy = NULL;
|
||||
static int dbus_old_brightness = 0;
|
||||
|
||||
static void dbus_brightness_init(GObject *src, GAsyncResult *res, gpointer *user_data)
|
||||
static void
|
||||
dbus_brightness_init(GObject *src, GAsyncResult *res, gpointer *user_data)
|
||||
{
|
||||
GError *err = NULL;
|
||||
dbus_brightness_proxy = g_dbus_proxy_new_finish (res, &err);
|
||||
dbus_brightness_proxy = g_dbus_proxy_new_finish(res, &err);
|
||||
if (!dbus_brightness_proxy || err) {
|
||||
printf("Failed to connect to dbus brightness service %s\n", err->message);
|
||||
printf("Failed to connect to dbus brightness service %s\n",
|
||||
err->message);
|
||||
g_object_unref(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void mp_flash_gtk_init(GDBusConnection *conn)
|
||||
void
|
||||
mp_flash_gtk_init(GDBusConnection *conn)
|
||||
{
|
||||
g_dbus_proxy_new(conn,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
"org.gnome.SettingsDaemon.Power",
|
||||
"/org/gnome/SettingsDaemon/Power",
|
||||
"org.gnome.SettingsDaemon.Power.Screen",
|
||||
NULL,
|
||||
(GAsyncReadyCallback)dbus_brightness_init,
|
||||
NULL);
|
||||
g_dbus_proxy_new(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
|
||||
"org.gnome.SettingsDaemon.Power",
|
||||
"/org/gnome/SettingsDaemon/Power",
|
||||
"org.gnome.SettingsDaemon.Power.Screen", NULL,
|
||||
(GAsyncReadyCallback)dbus_brightness_init, NULL);
|
||||
|
||||
// Create a full screen full white window as a flash
|
||||
GtkWidget *window = gtk_window_new();
|
||||
|
@ -88,7 +87,8 @@ void mp_flash_gtk_init(GDBusConnection *conn)
|
|||
flash_window = window;
|
||||
}
|
||||
|
||||
void mp_flash_gtk_clean()
|
||||
void
|
||||
mp_flash_gtk_clean()
|
||||
{
|
||||
gtk_window_destroy(GTK_WINDOW(flash_window));
|
||||
g_object_unref(dbus_brightness_proxy);
|
||||
|
@ -107,33 +107,28 @@ void
|
|||
mp_flash_free(MPFlash *flash)
|
||||
{
|
||||
switch (flash->type) {
|
||||
case FLASH_TYPE_LED:
|
||||
close(flash->led.fd);
|
||||
break;
|
||||
case FLASH_TYPE_DISPLAY:
|
||||
break;
|
||||
case FLASH_TYPE_LED:
|
||||
close(flash->led.fd);
|
||||
break;
|
||||
case FLASH_TYPE_DISPLAY:
|
||||
break;
|
||||
}
|
||||
|
||||
free(flash);
|
||||
}
|
||||
|
||||
static void set_display_brightness(int brightness)
|
||||
static void
|
||||
set_display_brightness(int brightness)
|
||||
{
|
||||
g_dbus_proxy_call(dbus_brightness_proxy,
|
||||
"org.freedesktop.DBus.Properties.Set",
|
||||
g_variant_new(
|
||||
"(ssv)",
|
||||
"org.gnome.SettingsDaemon.Power.Screen",
|
||||
"Brightness",
|
||||
g_variant_new("i", brightness)),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
g_dbus_proxy_call(
|
||||
dbus_brightness_proxy, "org.freedesktop.DBus.Properties.Set",
|
||||
g_variant_new("(ssv)", "org.gnome.SettingsDaemon.Power.Screen",
|
||||
"Brightness", g_variant_new("i", brightness)),
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void brightness_received(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
|
||||
static void
|
||||
brightness_received(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *result = g_dbus_proxy_call_finish(proxy, res, &error);
|
||||
|
@ -155,7 +150,8 @@ static void brightness_received(GDBusProxy *proxy, GAsyncResult *res, gpointer u
|
|||
g_variant_unref(result);
|
||||
}
|
||||
|
||||
static bool show_display_flash(MPFlash *flash)
|
||||
static bool
|
||||
show_display_flash(MPFlash *flash)
|
||||
{
|
||||
if (!flash_window)
|
||||
return false;
|
||||
|
@ -166,17 +162,12 @@ static bool show_display_flash(MPFlash *flash)
|
|||
if (!dbus_brightness_proxy)
|
||||
return false;
|
||||
|
||||
g_dbus_proxy_call(dbus_brightness_proxy,
|
||||
"org.freedesktop.DBus.Properties.Get",
|
||||
g_variant_new(
|
||||
"(ss)",
|
||||
"org.gnome.SettingsDaemon.Power.Screen",
|
||||
"Brightness"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)brightness_received,
|
||||
NULL);
|
||||
g_dbus_proxy_call(
|
||||
dbus_brightness_proxy, "org.freedesktop.DBus.Properties.Get",
|
||||
g_variant_new("(ss)", "org.gnome.SettingsDaemon.Power.Screen",
|
||||
"Brightness"),
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL,
|
||||
(GAsyncReadyCallback)brightness_received, NULL);
|
||||
|
||||
set_display_brightness(100);
|
||||
|
||||
|
@ -187,17 +178,18 @@ void
|
|||
mp_flash_enable(MPFlash *flash)
|
||||
{
|
||||
switch (flash->type) {
|
||||
case FLASH_TYPE_LED:
|
||||
lseek(flash->led.fd, 0, SEEK_SET);
|
||||
dprintf(flash->led.fd, "1\n");
|
||||
break;
|
||||
case FLASH_TYPE_DISPLAY:
|
||||
g_main_context_invoke(NULL, (GSourceFunc)show_display_flash, flash);
|
||||
break;
|
||||
case FLASH_TYPE_LED:
|
||||
lseek(flash->led.fd, 0, SEEK_SET);
|
||||
dprintf(flash->led.fd, "1\n");
|
||||
break;
|
||||
case FLASH_TYPE_DISPLAY:
|
||||
g_main_context_invoke(NULL, (GSourceFunc)show_display_flash, flash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool hide_display_flash(MPFlash *flash)
|
||||
static bool
|
||||
hide_display_flash(MPFlash *flash)
|
||||
{
|
||||
if (!flash_window)
|
||||
return false;
|
||||
|
@ -212,12 +204,11 @@ void
|
|||
mp_flash_disable(MPFlash *flash)
|
||||
{
|
||||
switch (flash->type) {
|
||||
case FLASH_TYPE_LED:
|
||||
// Flash gets reset automatically
|
||||
break;
|
||||
case FLASH_TYPE_DISPLAY:
|
||||
g_main_context_invoke(NULL, (GSourceFunc)hide_display_flash, flash);
|
||||
break;
|
||||
case FLASH_TYPE_LED:
|
||||
// Flash gets reset automatically
|
||||
break;
|
||||
case FLASH_TYPE_DISPLAY:
|
||||
g_main_context_invoke(NULL, (GSourceFunc)hide_display_flash, flash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,32 +8,33 @@
|
|||
#include <gmodule.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
void gl_util_check_error(const char *file, int line)
|
||||
void
|
||||
gl_util_check_error(const char *file, int line)
|
||||
{
|
||||
GLenum error = glGetError();
|
||||
|
||||
const char *name;
|
||||
switch (error) {
|
||||
case GL_NO_ERROR:
|
||||
return; // no error
|
||||
case GL_INVALID_ENUM:
|
||||
name = "GL_INVALID_ENUM";
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
name = "GL_INVALID_VALUE";
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
name = "GL_INVALID_OPERATION";
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
name = "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
name = "GL_OUT_OF_MEMORY";
|
||||
break;
|
||||
default:
|
||||
name = "UNKNOWN ERROR!";
|
||||
break;
|
||||
case GL_NO_ERROR:
|
||||
return; // no error
|
||||
case GL_INVALID_ENUM:
|
||||
name = "GL_INVALID_ENUM";
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
name = "GL_INVALID_VALUE";
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
name = "GL_INVALID_OPERATION";
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
name = "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
name = "GL_OUT_OF_MEMORY";
|
||||
break;
|
||||
default:
|
||||
name = "UNKNOWN ERROR!";
|
||||
break;
|
||||
}
|
||||
|
||||
printf("GL error at %s:%d - %s\n", file, line, name);
|
||||
|
@ -42,7 +43,8 @@ void gl_util_check_error(const char *file, int line)
|
|||
}
|
||||
|
||||
GLuint
|
||||
gl_util_load_shader(const char *resource, GLenum type, const char **extra_sources, size_t num_extra)
|
||||
gl_util_load_shader(const char *resource, GLenum type, const char **extra_sources,
|
||||
size_t num_extra)
|
||||
{
|
||||
GdkGLContext *context = gdk_gl_context_get_current();
|
||||
assert(context);
|
||||
|
@ -63,7 +65,9 @@ gl_util_load_shader(const char *resource, GLenum type, const char **extra_source
|
|||
int major, minor;
|
||||
gdk_gl_context_get_version(context, &major, &minor);
|
||||
char context_info_buf[128];
|
||||
snprintf(context_info_buf, 128, "#define %s\n#define GL_%d\n#define GL_%d_%d\n", is_es ? "GL_ES" : "GL_NO_ES", major, major, minor);
|
||||
snprintf(context_info_buf, 128,
|
||||
"#define %s\n#define GL_%d\n#define GL_%d_%d\n",
|
||||
is_es ? "GL_ES" : "GL_NO_ES", major, major, minor);
|
||||
|
||||
gsize glib_size = 0;
|
||||
const GLchar *source = g_bytes_get_data(bytes, &glib_size);
|
||||
|
@ -151,18 +155,27 @@ gl_util_link_program(GLuint *shaders, size_t num_shaders)
|
|||
|
||||
static const GLfloat quad_data[] = {
|
||||
// Vertices
|
||||
-1, -1,
|
||||
1, -1,
|
||||
-1, 1,
|
||||
1, 1,
|
||||
-1,
|
||||
-1,
|
||||
1,
|
||||
-1,
|
||||
-1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
// Texcoords
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
};
|
||||
|
||||
GLuint gl_util_new_quad()
|
||||
GLuint
|
||||
gl_util_new_quad()
|
||||
{
|
||||
GdkGLContext *context = gdk_gl_context_get_current();
|
||||
assert(context);
|
||||
|
@ -174,7 +187,8 @@ GLuint gl_util_new_quad()
|
|||
glGenBuffers(1, &buffer);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_data), quad_data,
|
||||
GL_STATIC_DRAW);
|
||||
check_gl();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
@ -184,18 +198,21 @@ GLuint gl_util_new_quad()
|
|||
}
|
||||
}
|
||||
|
||||
void gl_util_bind_quad(GLuint buffer)
|
||||
void
|
||||
gl_util_bind_quad(GLuint buffer)
|
||||
{
|
||||
GdkGLContext *context = gdk_gl_context_get_current();
|
||||
assert(context);
|
||||
|
||||
if (gdk_gl_context_get_use_es(context)) {
|
||||
glVertexAttribPointer(GL_UTIL_VERTEX_ATTRIBUTE, 2, GL_FLOAT, 0, 0, quad_data);
|
||||
glVertexAttribPointer(GL_UTIL_VERTEX_ATTRIBUTE, 2, GL_FLOAT, 0, 0,
|
||||
quad_data);
|
||||
check_gl();
|
||||
glEnableVertexAttribArray(GL_UTIL_VERTEX_ATTRIBUTE);
|
||||
check_gl();
|
||||
|
||||
glVertexAttribPointer(GL_UTIL_TEX_COORD_ATTRIBUTE, 2, GL_FLOAT, 0, 0, quad_data + 8);
|
||||
glVertexAttribPointer(GL_UTIL_TEX_COORD_ATTRIBUTE, 2, GL_FLOAT, 0, 0,
|
||||
quad_data + 8);
|
||||
check_gl();
|
||||
glEnableVertexAttribArray(GL_UTIL_TEX_COORD_ATTRIBUTE);
|
||||
check_gl();
|
||||
|
@ -203,17 +220,20 @@ void gl_util_bind_quad(GLuint buffer)
|
|||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
check_gl();
|
||||
|
||||
glVertexAttribPointer(GL_UTIL_VERTEX_ATTRIBUTE, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glVertexAttribPointer(GL_UTIL_VERTEX_ATTRIBUTE, 2, GL_FLOAT,
|
||||
GL_FALSE, 0, 0);
|
||||
glEnableVertexAttribArray(GL_UTIL_VERTEX_ATTRIBUTE);
|
||||
check_gl();
|
||||
|
||||
glVertexAttribPointer(GL_UTIL_TEX_COORD_ATTRIBUTE, 2, GL_FLOAT, GL_FALSE, 0, (void*) (8 * sizeof(float)));
|
||||
glVertexAttribPointer(GL_UTIL_TEX_COORD_ATTRIBUTE, 2, GL_FLOAT,
|
||||
GL_FALSE, 0, (void *)(8 * sizeof(float)));
|
||||
glEnableVertexAttribArray(GL_UTIL_TEX_COORD_ATTRIBUTE);
|
||||
check_gl();
|
||||
}
|
||||
}
|
||||
|
||||
void gl_util_draw_quad(GLuint buffer)
|
||||
void
|
||||
gl_util_draw_quad(GLuint buffer)
|
||||
{
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
check_gl();
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
#define check_gl() gl_util_check_error(__FILE__, __LINE__)
|
||||
void gl_util_check_error(const char *file, int line);
|
||||
|
||||
GLuint gl_util_load_shader(const char *resource, GLenum type, const char **extra_sources, size_t num_extra);
|
||||
GLuint gl_util_load_shader(const char *resource, GLenum type,
|
||||
const char **extra_sources, size_t num_extra);
|
||||
GLuint gl_util_link_program(GLuint *shaders, size_t num_shaders);
|
||||
|
||||
GLuint gl_util_new_quad();
|
||||
|
|
|
@ -30,8 +30,10 @@ gles2_debayer_new(MPPixelFormat format)
|
|||
check_gl();
|
||||
|
||||
GLuint shaders[] = {
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/debayer.vert", GL_VERTEX_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/debayer.frag", GL_FRAGMENT_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/debayer.vert",
|
||||
GL_VERTEX_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/debayer.frag",
|
||||
GL_FRAGMENT_SHADER, NULL, 0),
|
||||
};
|
||||
|
||||
GLuint program = gl_util_link_program(shaders, 2);
|
||||
|
@ -46,7 +48,8 @@ gles2_debayer_new(MPPixelFormat format)
|
|||
self->uniform_transform = glGetUniformLocation(self->program, "transform");
|
||||
self->uniform_pixel_size = glGetUniformLocation(self->program, "pixel_size");
|
||||
self->uniform_texture = glGetUniformLocation(self->program, "texture");
|
||||
self->uniform_color_matrix = glGetUniformLocation(self->program, "color_matrix");
|
||||
self->uniform_color_matrix =
|
||||
glGetUniformLocation(self->program, "color_matrix");
|
||||
check_gl();
|
||||
|
||||
self->quad = gl_util_new_quad();
|
||||
|
@ -74,12 +77,10 @@ gles2_debayer_use(GLES2Debayer *self)
|
|||
}
|
||||
|
||||
void
|
||||
gles2_debayer_configure(GLES2Debayer *self,
|
||||
const uint32_t dst_width, const uint32_t dst_height,
|
||||
const uint32_t src_width, const uint32_t src_height,
|
||||
const uint32_t rotation,
|
||||
const bool mirrored,
|
||||
const float *colormatrix,
|
||||
gles2_debayer_configure(GLES2Debayer *self, const uint32_t dst_width,
|
||||
const uint32_t dst_height, const uint32_t src_width,
|
||||
const uint32_t src_height, const uint32_t rotation,
|
||||
const bool mirrored, const float *colormatrix,
|
||||
const uint8_t blacklevel)
|
||||
{
|
||||
glViewport(0, 0, dst_width, dst_height);
|
||||
|
@ -92,9 +93,11 @@ gles2_debayer_configure(GLES2Debayer *self,
|
|||
GLfloat cos_rot = rotation_list[(rotation_index + 1) % 4];
|
||||
GLfloat scale_x = mirrored ? 1 : -1;
|
||||
GLfloat matrix[9] = {
|
||||
cos_rot * scale_x, sin_rot, 0,
|
||||
// clang-format off
|
||||
cos_rot * scale_x, sin_rot, 0,
|
||||
-sin_rot * scale_x, cos_rot, 0,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
// clang-format on
|
||||
};
|
||||
glUniformMatrix3fv(self->uniform_transform, 1, GL_FALSE, matrix);
|
||||
check_gl();
|
||||
|
@ -110,14 +113,18 @@ gles2_debayer_configure(GLES2Debayer *self,
|
|||
for (int j = 0; j < 3; ++j)
|
||||
transposed[i + j * 3] = colormatrix[j + i * 3];
|
||||
|
||||
glUniformMatrix3fv(self->uniform_color_matrix, 1, GL_FALSE, transposed);
|
||||
glUniformMatrix3fv(self->uniform_color_matrix, 1, GL_FALSE,
|
||||
transposed);
|
||||
} else {
|
||||
static const GLfloat identity[9] = {
|
||||
// clang-format off
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
// clang-format on
|
||||
};
|
||||
glUniformMatrix3fv(self->uniform_color_matrix, 1, GL_FALSE, identity);
|
||||
glUniformMatrix3fv(self->uniform_color_matrix, 1, GL_FALSE,
|
||||
identity);
|
||||
}
|
||||
check_gl();
|
||||
}
|
||||
|
@ -127,7 +134,8 @@ gles2_debayer_process(GLES2Debayer *self, GLuint dst_id, GLuint source_id)
|
|||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, self->frame_buffer);
|
||||
glBindTexture(GL_TEXTURE_2D, dst_id);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_id, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
dst_id, 0);
|
||||
check_gl();
|
||||
|
||||
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
||||
|
|
|
@ -5,17 +5,15 @@
|
|||
|
||||
typedef struct _GLES2Debayer GLES2Debayer;
|
||||
|
||||
GLES2Debayer* gles2_debayer_new(MPPixelFormat format);
|
||||
GLES2Debayer *gles2_debayer_new(MPPixelFormat format);
|
||||
void gles2_debayer_free(GLES2Debayer *self);
|
||||
|
||||
void gles2_debayer_use(GLES2Debayer *self);
|
||||
|
||||
void gles2_debayer_configure(GLES2Debayer *self,
|
||||
const uint32_t dst_width, const uint32_t dst_height,
|
||||
const uint32_t src_width, const uint32_t src_height,
|
||||
const uint32_t rotation,
|
||||
const bool mirrored,
|
||||
const float *colormatrix,
|
||||
void gles2_debayer_configure(GLES2Debayer *self, const uint32_t dst_width,
|
||||
const uint32_t dst_height, const uint32_t src_width,
|
||||
const uint32_t src_height, const uint32_t rotation,
|
||||
const bool mirrored, const float *colormatrix,
|
||||
const uint8_t blacklevel);
|
||||
|
||||
void gles2_debayer_process(GLES2Debayer *self, GLuint dst_id, GLuint source_id);
|
||||
|
|
|
@ -147,7 +147,8 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
|
|||
|
||||
info->video_fd = open(dev_name, O_RDWR);
|
||||
if (info->video_fd == -1) {
|
||||
g_printerr("Could not open %s: %s\n", dev_name, strerror(errno));
|
||||
g_printerr("Could not open %s: %s\n", dev_name,
|
||||
strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -188,7 +189,8 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
|
|||
|
||||
info->fd = open(info->dev_fname, O_RDWR);
|
||||
if (info->fd == -1) {
|
||||
g_printerr("Could not open %s: %s\n", info->dev_fname, strerror(errno));
|
||||
g_printerr("Could not open %s: %s\n", info->dev_fname,
|
||||
strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -204,8 +206,8 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
|
|||
if (mp_camera_query_control(info->camera, V4L2_CID_FOCUS_AUTO,
|
||||
NULL)) {
|
||||
info->has_auto_focus_continuous = true;
|
||||
mp_camera_control_set_bool_bg(info->camera, V4L2_CID_FOCUS_AUTO,
|
||||
true);
|
||||
mp_camera_control_set_bool_bg(info->camera,
|
||||
V4L2_CID_FOCUS_AUTO, true);
|
||||
}
|
||||
if (mp_camera_query_control(info->camera, V4L2_CID_AUTO_FOCUS_START,
|
||||
NULL)) {
|
||||
|
@ -254,7 +256,7 @@ static void
|
|||
clean_cameras()
|
||||
{
|
||||
for (size_t i = 0; i < MP_MAX_CAMERAS; ++i) {
|
||||
struct camera_info* info = &cameras[i];
|
||||
struct camera_info *info = &cameras[i];
|
||||
if (info->camera) {
|
||||
mp_camera_free(info->camera);
|
||||
info->camera = NULL;
|
||||
|
@ -378,9 +380,11 @@ release_buffer(MPPipeline *pipeline, const uint32_t *buffer_index)
|
|||
mp_camera_release_buffer(info->camera, *buffer_index);
|
||||
}
|
||||
|
||||
void mp_io_pipeline_release_buffer(uint32_t buffer_index)
|
||||
void
|
||||
mp_io_pipeline_release_buffer(uint32_t buffer_index)
|
||||
{
|
||||
mp_pipeline_invoke(pipeline, (MPPipelineCallback) release_buffer, &buffer_index, sizeof(uint32_t));
|
||||
mp_pipeline_invoke(pipeline, (MPPipelineCallback)release_buffer,
|
||||
&buffer_index, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static pid_t focus_continuous_task = 0;
|
||||
|
@ -389,16 +393,16 @@ static void
|
|||
start_focus(struct camera_info *info)
|
||||
{
|
||||
// only run 1 manual focus at once
|
||||
if (!mp_camera_check_task_complete(info->camera, start_focus_task)
|
||||
|| !mp_camera_check_task_complete(info->camera, focus_continuous_task))
|
||||
if (!mp_camera_check_task_complete(info->camera, start_focus_task) ||
|
||||
!mp_camera_check_task_complete(info->camera, focus_continuous_task))
|
||||
return;
|
||||
|
||||
if (info->has_auto_focus_continuous) {
|
||||
focus_continuous_task = mp_camera_control_set_bool_bg(info->camera,
|
||||
V4L2_CID_FOCUS_AUTO, 1);
|
||||
focus_continuous_task = mp_camera_control_set_bool_bg(
|
||||
info->camera, V4L2_CID_FOCUS_AUTO, 1);
|
||||
} else if (info->has_auto_focus_start) {
|
||||
start_focus_task = mp_camera_control_set_bool_bg(info->camera,
|
||||
V4L2_CID_AUTO_FOCUS_START, 1);
|
||||
start_focus_task = mp_camera_control_set_bool_bg(
|
||||
info->camera, V4L2_CID_AUTO_FOCUS_START, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,34 +423,34 @@ update_controls()
|
|||
|
||||
if (current_controls.gain_is_manual != desired_controls.gain_is_manual) {
|
||||
mp_camera_control_set_bool_bg(info->camera, V4L2_CID_AUTOGAIN,
|
||||
!desired_controls.gain_is_manual);
|
||||
!desired_controls.gain_is_manual);
|
||||
}
|
||||
|
||||
if (desired_controls.gain_is_manual &&
|
||||
current_controls.gain != desired_controls.gain) {
|
||||
mp_camera_control_set_int32_bg(info->camera, info->gain_ctrl,
|
||||
desired_controls.gain);
|
||||
desired_controls.gain);
|
||||
}
|
||||
|
||||
if (current_controls.exposure_is_manual !=
|
||||
desired_controls.exposure_is_manual) {
|
||||
mp_camera_control_set_int32_bg(info->camera, V4L2_CID_EXPOSURE_AUTO,
|
||||
desired_controls.exposure_is_manual ?
|
||||
V4L2_EXPOSURE_MANUAL :
|
||||
V4L2_EXPOSURE_AUTO);
|
||||
desired_controls.exposure_is_manual ?
|
||||
V4L2_EXPOSURE_MANUAL :
|
||||
V4L2_EXPOSURE_AUTO);
|
||||
}
|
||||
|
||||
if (desired_controls.exposure_is_manual &&
|
||||
current_controls.exposure != desired_controls.exposure) {
|
||||
mp_camera_control_set_int32_bg(info->camera, V4L2_CID_EXPOSURE,
|
||||
desired_controls.exposure);
|
||||
desired_controls.exposure);
|
||||
}
|
||||
|
||||
current_controls = desired_controls;
|
||||
}
|
||||
|
||||
static void
|
||||
on_frame(MPBuffer buffer, void * _data)
|
||||
on_frame(MPBuffer buffer, void *_data)
|
||||
{
|
||||
// Only update controls right after a frame was captured
|
||||
update_controls();
|
||||
|
@ -489,14 +493,14 @@ on_frame(MPBuffer buffer, void * _data)
|
|||
|
||||
// Restore the auto exposure and gain if needed
|
||||
if (!current_controls.exposure_is_manual) {
|
||||
mp_camera_control_set_int32_bg(info->camera,
|
||||
V4L2_CID_EXPOSURE_AUTO,
|
||||
V4L2_EXPOSURE_AUTO);
|
||||
mp_camera_control_set_int32_bg(
|
||||
info->camera, V4L2_CID_EXPOSURE_AUTO,
|
||||
V4L2_EXPOSURE_AUTO);
|
||||
}
|
||||
|
||||
if (!current_controls.gain_is_manual) {
|
||||
mp_camera_control_set_bool_bg(info->camera,
|
||||
V4L2_CID_AUTOGAIN, true);
|
||||
mp_camera_control_set_bool_bg(
|
||||
info->camera, V4L2_CID_AUTOGAIN, true);
|
||||
}
|
||||
|
||||
// Go back to preview mode
|
||||
|
@ -594,11 +598,10 @@ update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
|
|||
desired_controls.exposure_is_manual = state->exposure_is_manual;
|
||||
desired_controls.exposure = state->exposure;
|
||||
|
||||
has_changed =
|
||||
has_changed
|
||||
|| memcmp(&previous_desired, &desired_controls,
|
||||
sizeof(struct control_state)) != 0
|
||||
|| flash_enabled != state->flash_enabled;
|
||||
has_changed = has_changed ||
|
||||
memcmp(&previous_desired, &desired_controls,
|
||||
sizeof(struct control_state)) != 0 ||
|
||||
flash_enabled != state->flash_enabled;
|
||||
|
||||
flash_enabled = state->flash_enabled;
|
||||
}
|
||||
|
|
346
src/main.c
346
src/main.c
|
@ -24,7 +24,7 @@
|
|||
#include <wordexp.h>
|
||||
#include <zbar.h>
|
||||
|
||||
#define RENDERDOC
|
||||
// #define RENDERDOC
|
||||
|
||||
#ifdef RENDERDOC
|
||||
#include <dlfcn.h>
|
||||
|
@ -158,7 +158,8 @@ mp_main_update_state(const struct mp_main_state *state)
|
|||
(GSourceFunc)update_state, state_copy, free);
|
||||
}
|
||||
|
||||
static bool set_zbar_result(MPZBarScanResult *result)
|
||||
static bool
|
||||
set_zbar_result(MPZBarScanResult *result)
|
||||
{
|
||||
if (zbar_result) {
|
||||
for (uint8_t i = 0; i < zbar_result->size; ++i) {
|
||||
|
@ -174,7 +175,8 @@ static bool set_zbar_result(MPZBarScanResult *result)
|
|||
return false;
|
||||
}
|
||||
|
||||
void mp_main_set_zbar_result(MPZBarScanResult *result)
|
||||
void
|
||||
mp_main_set_zbar_result(MPZBarScanResult *result)
|
||||
{
|
||||
g_main_context_invoke_full(g_main_context_default(), G_PRIORITY_DEFAULT_IDLE,
|
||||
(GSourceFunc)set_zbar_result, result, NULL);
|
||||
|
@ -223,7 +225,8 @@ capture_completed(struct capture_completed_args *args)
|
|||
void
|
||||
mp_main_capture_completed(GdkTexture *thumb, const char *fname)
|
||||
{
|
||||
struct capture_completed_args *args = malloc(sizeof(struct capture_completed_args));
|
||||
struct capture_completed_args *args =
|
||||
malloc(sizeof(struct capture_completed_args));
|
||||
args->thumb = thumb;
|
||||
args->fname = g_strdup(fname);
|
||||
g_main_context_invoke_full(g_main_context_default(), G_PRIORITY_DEFAULT_IDLE,
|
||||
|
@ -255,8 +258,10 @@ preview_realize(GtkGLArea *area)
|
|||
}
|
||||
|
||||
GLuint blit_shaders[] = {
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/blit.vert", GL_VERTEX_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/blit.frag", GL_FRAGMENT_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/blit.vert",
|
||||
GL_VERTEX_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/blit.frag",
|
||||
GL_FRAGMENT_SHADER, NULL, 0),
|
||||
};
|
||||
|
||||
blit_program = gl_util_link_program(blit_shaders, 2);
|
||||
|
@ -268,8 +273,10 @@ preview_realize(GtkGLArea *area)
|
|||
blit_uniform_texture = glGetUniformLocation(blit_program, "texture");
|
||||
|
||||
GLuint solid_shaders[] = {
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/solid.vert", GL_VERTEX_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/solid.frag", GL_FRAGMENT_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/solid.vert",
|
||||
GL_VERTEX_SHADER, NULL, 0),
|
||||
gl_util_load_shader("/org/postmarketos/Megapixels/solid.frag",
|
||||
GL_FRAGMENT_SHADER, NULL, 0),
|
||||
};
|
||||
|
||||
solid_program = gl_util_link_program(solid_shaders, 2);
|
||||
|
@ -294,11 +301,14 @@ position_preview(float *offset_x, float *offset_y, float *size_x, float *size_y)
|
|||
}
|
||||
|
||||
int scale_factor = gtk_widget_get_scale_factor(preview);
|
||||
int top_height = gtk_widget_get_allocated_height(preview_top_box) * scale_factor;
|
||||
int bottom_height = gtk_widget_get_allocated_height(preview_bottom_box) * scale_factor;
|
||||
int top_height =
|
||||
gtk_widget_get_allocated_height(preview_top_box) * scale_factor;
|
||||
int bottom_height =
|
||||
gtk_widget_get_allocated_height(preview_bottom_box) * scale_factor;
|
||||
int inner_height = preview_height - top_height - bottom_height;
|
||||
|
||||
double scale = MIN(preview_width / (float) buffer_width, preview_height / (float) buffer_height);
|
||||
double scale = MIN(preview_width / (float)buffer_width,
|
||||
preview_height / (float)buffer_height);
|
||||
|
||||
*size_x = scale * buffer_width;
|
||||
*size_y = scale * buffer_height;
|
||||
|
@ -310,7 +320,6 @@ position_preview(float *offset_x, float *offset_y, float *size_x, float *size_y)
|
|||
} else {
|
||||
*offset_y = top_height + (inner_height - *size_y) / 2.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -325,7 +334,9 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
|
|||
}
|
||||
|
||||
#ifdef RENDERDOC
|
||||
if (rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
|
||||
if (rdoc_api) {
|
||||
rdoc_api->StartFrameCapture(NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
glClearColor(0, 0, 0, 1);
|
||||
|
@ -333,10 +344,7 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
|
|||
|
||||
float offset_x, offset_y, size_x, size_y;
|
||||
position_preview(&offset_x, &offset_y, &size_x, &size_y);
|
||||
glViewport(offset_x,
|
||||
preview_height - size_y - offset_y,
|
||||
size_x,
|
||||
size_y);
|
||||
glViewport(offset_x, preview_height - size_y - offset_y, size_x, size_y);
|
||||
|
||||
if (current_preview_buffer) {
|
||||
glUseProgram(blit_program);
|
||||
|
@ -347,15 +355,19 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
|
|||
GLfloat sin_rot = rotation_list[rotation_index];
|
||||
GLfloat cos_rot = rotation_list[(4 + rotation_index - 1) % 4];
|
||||
GLfloat matrix[9] = {
|
||||
cos_rot, sin_rot, 0,
|
||||
// clang-format off
|
||||
cos_rot, sin_rot, 0,
|
||||
-sin_rot, cos_rot, 0,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
// clang-format on
|
||||
};
|
||||
glUniformMatrix3fv(blit_uniform_transform, 1, GL_FALSE, matrix);
|
||||
check_gl();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mp_process_pipeline_buffer_get_texture_id(current_preview_buffer));
|
||||
glBindTexture(GL_TEXTURE_2D,
|
||||
mp_process_pipeline_buffer_get_texture_id(
|
||||
current_preview_buffer));
|
||||
glUniform1i(blit_uniform_texture, 0);
|
||||
check_gl();
|
||||
|
||||
|
@ -388,20 +400,27 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
|
|||
};
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
vertices[i * 2] = 2 * vertices[i * 2] / preview_buffer_width - 1.0;
|
||||
vertices[i * 2 + 1] = 1.0 - 2 * vertices[i * 2 + 1] / preview_buffer_height;
|
||||
vertices[i * 2] =
|
||||
2 * vertices[i * 2] / preview_buffer_width -
|
||||
1.0;
|
||||
vertices[i * 2 + 1] =
|
||||
1.0 - 2 * vertices[i * 2 + 1] /
|
||||
preview_buffer_height;
|
||||
}
|
||||
|
||||
if (gtk_gl_area_get_use_es(area)) {
|
||||
glVertexAttribPointer(GL_UTIL_VERTEX_ATTRIBUTE, 2, GL_FLOAT, 0, 0, vertices);
|
||||
glVertexAttribPointer(GL_UTIL_VERTEX_ATTRIBUTE, 2,
|
||||
GL_FLOAT, 0, 0, vertices);
|
||||
check_gl();
|
||||
glEnableVertexAttribArray(GL_UTIL_VERTEX_ATTRIBUTE);
|
||||
check_gl();
|
||||
} else {
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
|
||||
vertices, GL_STREAM_DRAW);
|
||||
check_gl();
|
||||
|
||||
glVertexAttribPointer(GL_UTIL_VERTEX_ATTRIBUTE, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glVertexAttribPointer(GL_UTIL_VERTEX_ATTRIBUTE, 2,
|
||||
GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glEnableVertexAttribArray(GL_UTIL_VERTEX_ATTRIBUTE);
|
||||
check_gl();
|
||||
}
|
||||
|
@ -417,7 +436,9 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
|
|||
glFlush();
|
||||
|
||||
#ifdef RENDERDOC
|
||||
if(rdoc_api) rdoc_api->EndFrameCapture(NULL, NULL);
|
||||
if (rdoc_api) {
|
||||
rdoc_api->EndFrameCapture(NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
|
@ -446,7 +467,8 @@ run_open_last_action(GSimpleAction *action, GVariant *param, gpointer user_data)
|
|||
}
|
||||
sprintf(uri, "file://%s", last_path);
|
||||
if (!g_app_info_launch_default_for_uri(uri, NULL, &error)) {
|
||||
g_printerr("Could not launch image viewer for '%s': %s\n", uri, error->message);
|
||||
g_printerr("Could not launch image viewer for '%s': %s\n", uri,
|
||||
error->message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,14 +494,13 @@ run_capture_action(GSimpleAction *action, GVariant *param, gpointer user_data)
|
|||
void
|
||||
run_about_action(GSimpleAction *action, GVariant *param, GApplication *app)
|
||||
{
|
||||
gtk_show_about_dialog(NULL, "program-name", "Megapixels",
|
||||
"title", "Megapixels",
|
||||
"logo-icon-name", "org.postmarketos.Megapixels",
|
||||
"comments", "The postmarketOS camera application",
|
||||
"website", "https://sr.ht/~martijnbraam/megapixels",
|
||||
"version", VERSION,
|
||||
"license-type", GTK_LICENSE_GPL_3_0_ONLY,
|
||||
NULL);
|
||||
gtk_show_about_dialog(NULL, "program-name", "Megapixels", "title",
|
||||
"Megapixels", "logo-icon-name",
|
||||
"org.postmarketos.Megapixels", "comments",
|
||||
"The postmarketOS camera application", "website",
|
||||
"https://sr.ht/~martijnbraam/megapixels", "version",
|
||||
VERSION, "license-type", GTK_LICENSE_GPL_3_0_ONLY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -512,23 +533,19 @@ on_zbar_dialog_response(GtkDialog *dialog, int response, char *data)
|
|||
{
|
||||
GError *error = NULL;
|
||||
switch (response) {
|
||||
case GTK_RESPONSE_YES:
|
||||
if (!g_app_info_launch_default_for_uri(data,
|
||||
NULL, &error)) {
|
||||
g_printerr("Could not launch application: %s\n",
|
||||
error->message);
|
||||
}
|
||||
case GTK_RESPONSE_ACCEPT:
|
||||
{
|
||||
GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(dialog));
|
||||
gdk_clipboard_set_text(
|
||||
gdk_display_get_clipboard(display),
|
||||
data);
|
||||
case GTK_RESPONSE_YES:
|
||||
if (!g_app_info_launch_default_for_uri(data, NULL, &error)) {
|
||||
g_printerr("Could not launch application: %s\n",
|
||||
error->message);
|
||||
}
|
||||
case GTK_RESPONSE_CANCEL:
|
||||
break;
|
||||
default:
|
||||
g_printerr("Wrong dialog response: %d\n", response);
|
||||
case GTK_RESPONSE_ACCEPT: {
|
||||
GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(dialog));
|
||||
gdk_clipboard_set_text(gdk_display_get_clipboard(display), data);
|
||||
}
|
||||
case GTK_RESPONSE_CANCEL:
|
||||
break;
|
||||
default:
|
||||
g_printerr("Wrong dialog response: %d\n", response);
|
||||
}
|
||||
|
||||
g_free(data);
|
||||
|
@ -540,48 +557,31 @@ on_zbar_code_tapped(GtkWidget *widget, const MPZBarCode *code)
|
|||
{
|
||||
GtkWidget *dialog;
|
||||
GtkDialogFlags flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
|
||||
bool data_is_url = g_uri_is_valid(
|
||||
code->data, G_URI_FLAGS_PARSE_RELAXED, NULL);
|
||||
bool data_is_url =
|
||||
g_uri_is_valid(code->data, G_URI_FLAGS_PARSE_RELAXED, NULL);
|
||||
|
||||
char* data = strdup(code->data);
|
||||
char *data = strdup(code->data);
|
||||
|
||||
if (data_is_url) {
|
||||
dialog = gtk_message_dialog_new(
|
||||
GTK_WINDOW(gtk_widget_get_root(widget)),
|
||||
flags,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
"Found a URL '%s' encoded in a %s.",
|
||||
code->data,
|
||||
code->type);
|
||||
gtk_dialog_add_buttons(
|
||||
GTK_DIALOG(dialog),
|
||||
"_Open URL",
|
||||
GTK_RESPONSE_YES,
|
||||
NULL);
|
||||
GTK_WINDOW(gtk_widget_get_root(widget)), flags,
|
||||
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
|
||||
"Found a URL '%s' encoded in a %s.", code->data, code->type);
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(dialog), "_Open URL",
|
||||
GTK_RESPONSE_YES, NULL);
|
||||
} else {
|
||||
dialog = gtk_message_dialog_new(
|
||||
GTK_WINDOW(gtk_widget_get_root(widget)),
|
||||
flags,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
"Found data encoded in a %s.",
|
||||
code->type);
|
||||
gtk_message_dialog_format_secondary_markup (
|
||||
GTK_MESSAGE_DIALOG(dialog),
|
||||
"<small>%s</small>",
|
||||
code->data
|
||||
);
|
||||
GTK_WINDOW(gtk_widget_get_root(widget)), flags,
|
||||
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
|
||||
"Found data encoded in a %s.", code->type);
|
||||
gtk_message_dialog_format_secondary_markup(
|
||||
GTK_MESSAGE_DIALOG(dialog), "<small>%s</small>", code->data);
|
||||
}
|
||||
gtk_dialog_add_buttons(
|
||||
GTK_DIALOG(dialog),
|
||||
"_Copy",
|
||||
GTK_RESPONSE_ACCEPT,
|
||||
"_Cancel",
|
||||
GTK_RESPONSE_CANCEL,
|
||||
NULL);
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(dialog), "_Copy", GTK_RESPONSE_ACCEPT,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL, NULL);
|
||||
|
||||
g_signal_connect(dialog, "response", G_CALLBACK(on_zbar_dialog_response), data);
|
||||
g_signal_connect(dialog, "response", G_CALLBACK(on_zbar_dialog_response),
|
||||
data);
|
||||
|
||||
gtk_widget_show(GTK_WIDGET(dialog));
|
||||
}
|
||||
|
@ -589,7 +589,8 @@ on_zbar_code_tapped(GtkWidget *widget, const MPZBarCode *code)
|
|||
static void
|
||||
preview_pressed(GtkGestureClick *gesture, int n_press, double x, double y)
|
||||
{
|
||||
GtkWidget *widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture));
|
||||
GtkWidget *widget =
|
||||
gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture));
|
||||
int scale_factor = gtk_widget_get_scale_factor(widget);
|
||||
|
||||
// Tapped zbar result
|
||||
|
@ -598,13 +599,16 @@ preview_pressed(GtkGestureClick *gesture, int n_press, double x, double y)
|
|||
float offset_x, offset_y, size_x, size_y;
|
||||
position_preview(&offset_x, &offset_y, &size_x, &size_y);
|
||||
|
||||
int zbar_x = (x - offset_x) * scale_factor / size_x * preview_buffer_width;
|
||||
int zbar_y = (y - offset_y) * scale_factor / size_y * preview_buffer_height;
|
||||
int zbar_x = (x - offset_x) * scale_factor / size_x *
|
||||
preview_buffer_width;
|
||||
int zbar_y = (y - offset_y) * scale_factor / size_y *
|
||||
preview_buffer_height;
|
||||
|
||||
for (uint8_t i = 0; i < zbar_result->size; ++i) {
|
||||
MPZBarCode *code = &zbar_result->codes[i];
|
||||
|
||||
if (check_point_inside_bounds(zbar_x, zbar_y, code->bounds_x, code->bounds_y)) {
|
||||
if (check_point_inside_bounds(zbar_x, zbar_y, code->bounds_x,
|
||||
code->bounds_y)) {
|
||||
on_zbar_code_tapped(widget, code);
|
||||
return;
|
||||
}
|
||||
|
@ -647,8 +651,7 @@ run_close_settings_action(GSimpleAction *action, GVariant *param, gpointer user_
|
|||
// Update settings
|
||||
bool save_dng = g_settings_get_boolean(settings, "save-raw");
|
||||
|
||||
if (save_dng != setting_save_dng)
|
||||
{
|
||||
if (save_dng != setting_save_dng) {
|
||||
setting_save_dng = save_dng;
|
||||
update_io_pipeline();
|
||||
}
|
||||
|
@ -677,23 +680,25 @@ on_auto_controls_toggled(GtkToggleButton *button, void (*set_auto_fn)(bool))
|
|||
static void
|
||||
update_scale(GtkToggleButton *button, GtkScale *scale)
|
||||
{
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(scale), !gtk_toggle_button_get_active(button));
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(scale),
|
||||
!gtk_toggle_button_get_active(button));
|
||||
}
|
||||
|
||||
static void
|
||||
open_controls(GtkWidget *parent, const char *title_name,
|
||||
double min_value, double max_value, double current,
|
||||
bool auto_enabled,
|
||||
void (*set_fn)(double),
|
||||
void (*set_auto_fn)(bool))
|
||||
open_controls(GtkWidget *parent, const char *title_name, double min_value,
|
||||
double max_value, double current, bool auto_enabled,
|
||||
void (*set_fn)(double), void (*set_auto_fn)(bool))
|
||||
{
|
||||
GtkBuilder *builder = gtk_builder_new_from_resource(
|
||||
"/org/postmarketos/Megapixels/controls-popover.ui");
|
||||
GtkPopover *popover = GTK_POPOVER(gtk_builder_get_object(builder, "controls"));
|
||||
GtkPopover *popover =
|
||||
GTK_POPOVER(gtk_builder_get_object(builder, "controls"));
|
||||
GtkScale *scale = GTK_SCALE(gtk_builder_get_object(builder, "scale"));
|
||||
GtkLabel *title = GTK_LABEL(gtk_builder_get_object(builder, "title"));
|
||||
GtkLabel *value_label = GTK_LABEL(gtk_builder_get_object(builder, "value-label"));
|
||||
GtkToggleButton *auto_button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "auto-button"));
|
||||
GtkLabel *value_label =
|
||||
GTK_LABEL(gtk_builder_get_object(builder, "value-label"));
|
||||
GtkToggleButton *auto_button =
|
||||
GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "auto-button"));
|
||||
|
||||
gtk_label_set_label(title, title_name);
|
||||
|
||||
|
@ -706,9 +711,12 @@ open_controls(GtkWidget *parent, const char *title_name,
|
|||
gtk_toggle_button_set_active(auto_button, auto_enabled);
|
||||
update_scale(auto_button, scale);
|
||||
|
||||
g_signal_connect(adjustment, "value-changed", G_CALLBACK(on_controls_scale_changed), set_fn);
|
||||
g_signal_connect(adjustment, "value-changed", G_CALLBACK(update_value), value_label);
|
||||
g_signal_connect(auto_button, "toggled", G_CALLBACK(on_auto_controls_toggled), set_auto_fn);
|
||||
g_signal_connect(adjustment, "value-changed",
|
||||
G_CALLBACK(on_controls_scale_changed), set_fn);
|
||||
g_signal_connect(adjustment, "value-changed", G_CALLBACK(update_value),
|
||||
value_label);
|
||||
g_signal_connect(auto_button, "toggled",
|
||||
G_CALLBACK(on_auto_controls_toggled), set_auto_fn);
|
||||
g_signal_connect(auto_button, "toggled", G_CALLBACK(update_scale), scale);
|
||||
|
||||
gtk_widget_set_parent(GTK_WIDGET(popover), parent);
|
||||
|
@ -737,14 +745,14 @@ set_gain_auto(bool is_auto)
|
|||
static void
|
||||
open_iso_controls(GtkWidget *button, gpointer user_data)
|
||||
{
|
||||
open_controls(button, "ISO", 0, gain_max, gain, !gain_is_manual, set_gain, set_gain_auto);
|
||||
open_controls(button, "ISO", 0, gain_max, gain, !gain_is_manual, set_gain,
|
||||
set_gain_auto);
|
||||
}
|
||||
|
||||
static void
|
||||
set_shutter(double value)
|
||||
{
|
||||
int new_exposure =
|
||||
(int)(value / 360.0 * camera->capture_mode.height);
|
||||
int new_exposure = (int)(value / 360.0 * camera->capture_mode.height);
|
||||
if (new_exposure != exposure) {
|
||||
exposure = new_exposure;
|
||||
update_io_pipeline();
|
||||
|
@ -763,7 +771,8 @@ set_shutter_auto(bool is_auto)
|
|||
static void
|
||||
open_shutter_controls(GtkWidget *button, gpointer user_data)
|
||||
{
|
||||
open_controls(button, "Shutter", 1.0, 360.0, exposure, !exposure_is_manual, set_shutter, set_shutter_auto);
|
||||
open_controls(button, "Shutter", 1.0, 360.0, exposure, !exposure_is_manual,
|
||||
set_shutter, set_shutter_auto);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -772,7 +781,8 @@ flash_button_clicked(GtkWidget *button, gpointer user_data)
|
|||
flash_enabled = !flash_enabled;
|
||||
update_io_pipeline();
|
||||
|
||||
const char * icon_name = flash_enabled ? "flash-enabled-symbolic" : "flash-disabled-symbolic";
|
||||
const char *icon_name =
|
||||
flash_enabled ? "flash-enabled-symbolic" : "flash-disabled-symbolic";
|
||||
gtk_button_set_icon_name(GTK_BUTTON(button), icon_name);
|
||||
}
|
||||
|
||||
|
@ -795,15 +805,18 @@ create_simple_action(GtkApplication *app, const char *name, GCallback callback)
|
|||
return action;
|
||||
}
|
||||
|
||||
static void update_ui_rotation()
|
||||
static void
|
||||
update_ui_rotation()
|
||||
{
|
||||
if (device_rotation == 0 || device_rotation == 180) {
|
||||
// Portrait
|
||||
gtk_widget_set_halign(preview_top_box, GTK_ALIGN_FILL);
|
||||
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_top_box), GTK_ORIENTATION_VERTICAL);
|
||||
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_top_box),
|
||||
GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
gtk_widget_set_halign(preview_bottom_box, GTK_ALIGN_FILL);
|
||||
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_bottom_box), GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_bottom_box),
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
if (device_rotation == 0) {
|
||||
gtk_widget_set_valign(preview_top_box, GTK_ALIGN_START);
|
||||
|
@ -815,10 +828,12 @@ static void update_ui_rotation()
|
|||
} else {
|
||||
// Landscape
|
||||
gtk_widget_set_valign(preview_top_box, GTK_ALIGN_FILL);
|
||||
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_top_box), GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_top_box),
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
gtk_widget_set_valign(preview_bottom_box, GTK_ALIGN_FILL);
|
||||
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_bottom_box), GTK_ORIENTATION_VERTICAL);
|
||||
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_bottom_box),
|
||||
GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
if (device_rotation == 90) {
|
||||
gtk_widget_set_halign(preview_top_box, GTK_ALIGN_END);
|
||||
|
@ -830,7 +845,8 @@ static void update_ui_rotation()
|
|||
}
|
||||
}
|
||||
|
||||
static void display_config_received(GDBusConnection *conn, GAsyncResult *res, gpointer user_data)
|
||||
static void
|
||||
display_config_received(GDBusConnection *conn, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *result = g_dbus_connection_call_finish(conn, res, &error);
|
||||
|
@ -862,30 +878,20 @@ static void display_config_received(GDBusConnection *conn, GAsyncResult *res, gp
|
|||
g_variant_unref(result);
|
||||
}
|
||||
|
||||
static void update_screen_rotation(GDBusConnection *conn)
|
||||
static void
|
||||
update_screen_rotation(GDBusConnection *conn)
|
||||
{
|
||||
g_dbus_connection_call(conn,
|
||||
"org.gnome.Mutter.DisplayConfig",
|
||||
"/org/gnome/Mutter/DisplayConfig",
|
||||
"org.gnome.Mutter.DisplayConfig",
|
||||
"GetResources",
|
||||
NULL,
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
-1,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)display_config_received,
|
||||
NULL);
|
||||
g_dbus_connection_call(conn, "org.gnome.Mutter.DisplayConfig",
|
||||
"/org/gnome/Mutter/DisplayConfig",
|
||||
"org.gnome.Mutter.DisplayConfig", "GetResources",
|
||||
NULL, NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL,
|
||||
(GAsyncReadyCallback)display_config_received, NULL);
|
||||
}
|
||||
|
||||
static void on_screen_rotate(
|
||||
GDBusConnection *conn,
|
||||
const gchar *sender_name,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
static void
|
||||
on_screen_rotate(GDBusConnection *conn, const gchar *sender_name,
|
||||
const gchar *object_path, const gchar *interface_name,
|
||||
const gchar *signal_name, GVariant *parameters, gpointer user_data)
|
||||
{
|
||||
update_screen_rotation(conn);
|
||||
}
|
||||
|
@ -911,18 +917,25 @@ activate(GtkApplication *app, gpointer data)
|
|||
"/org/postmarketos/Megapixels/camera.ui");
|
||||
|
||||
GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
|
||||
GtkWidget *iso_button = GTK_WIDGET(gtk_builder_get_object(builder, "iso-controls-button"));
|
||||
GtkWidget *shutter_button = GTK_WIDGET(gtk_builder_get_object(builder, "shutter-controls-button"));
|
||||
flash_button = GTK_WIDGET(gtk_builder_get_object(builder, "flash-controls-button"));
|
||||
GtkWidget *setting_dng_button = GTK_WIDGET(gtk_builder_get_object(builder, "setting-raw"));
|
||||
GtkWidget *iso_button =
|
||||
GTK_WIDGET(gtk_builder_get_object(builder, "iso-controls-button"));
|
||||
GtkWidget *shutter_button = GTK_WIDGET(
|
||||
gtk_builder_get_object(builder, "shutter-controls-button"));
|
||||
flash_button =
|
||||
GTK_WIDGET(gtk_builder_get_object(builder, "flash-controls-button"));
|
||||
GtkWidget *setting_dng_button =
|
||||
GTK_WIDGET(gtk_builder_get_object(builder, "setting-raw"));
|
||||
preview = GTK_WIDGET(gtk_builder_get_object(builder, "preview"));
|
||||
main_stack = GTK_WIDGET(gtk_builder_get_object(builder, "main_stack"));
|
||||
open_last_stack = GTK_WIDGET(gtk_builder_get_object(builder, "open_last_stack"));
|
||||
open_last_stack =
|
||||
GTK_WIDGET(gtk_builder_get_object(builder, "open_last_stack"));
|
||||
thumb_last = GTK_WIDGET(gtk_builder_get_object(builder, "thumb_last"));
|
||||
process_spinner = GTK_WIDGET(gtk_builder_get_object(builder, "process_spinner"));
|
||||
process_spinner =
|
||||
GTK_WIDGET(gtk_builder_get_object(builder, "process_spinner"));
|
||||
scanned_codes = GTK_WIDGET(gtk_builder_get_object(builder, "scanned-codes"));
|
||||
preview_top_box = GTK_WIDGET(gtk_builder_get_object(builder, "top-box"));
|
||||
preview_bottom_box = GTK_WIDGET(gtk_builder_get_object(builder, "bottom-box"));
|
||||
preview_bottom_box =
|
||||
GTK_WIDGET(gtk_builder_get_object(builder, "bottom-box"));
|
||||
|
||||
g_signal_connect(window, "realize", G_CALLBACK(on_realize), NULL);
|
||||
|
||||
|
@ -934,14 +947,19 @@ activate(GtkApplication *app, gpointer data)
|
|||
gtk_widget_add_controller(preview, GTK_EVENT_CONTROLLER(click));
|
||||
|
||||
g_signal_connect(iso_button, "clicked", G_CALLBACK(open_iso_controls), NULL);
|
||||
g_signal_connect(shutter_button, "clicked", G_CALLBACK(open_shutter_controls), NULL);
|
||||
g_signal_connect(flash_button, "clicked", G_CALLBACK(flash_button_clicked), NULL);
|
||||
g_signal_connect(shutter_button, "clicked",
|
||||
G_CALLBACK(open_shutter_controls), NULL);
|
||||
g_signal_connect(flash_button, "clicked", G_CALLBACK(flash_button_clicked),
|
||||
NULL);
|
||||
|
||||
// Setup actions
|
||||
create_simple_action(app, "capture", G_CALLBACK(run_capture_action));
|
||||
create_simple_action(app, "switch-camera", G_CALLBACK(run_camera_switch_action));
|
||||
create_simple_action(app, "open-settings", G_CALLBACK(run_open_settings_action));
|
||||
create_simple_action(app, "close-settings", G_CALLBACK(run_close_settings_action));
|
||||
create_simple_action(app, "switch-camera",
|
||||
G_CALLBACK(run_camera_switch_action));
|
||||
create_simple_action(app, "open-settings",
|
||||
G_CALLBACK(run_open_settings_action));
|
||||
create_simple_action(app, "close-settings",
|
||||
G_CALLBACK(run_close_settings_action));
|
||||
create_simple_action(app, "open-last", G_CALLBACK(run_open_last_action));
|
||||
create_simple_action(app, "open-photos", G_CALLBACK(run_open_photos_action));
|
||||
create_simple_action(app, "about", G_CALLBACK(run_about_action));
|
||||
|
@ -956,23 +974,18 @@ activate(GtkApplication *app, gpointer data)
|
|||
|
||||
// Setup settings
|
||||
settings = g_settings_new("org.postmarketos.Megapixels");
|
||||
g_settings_bind (settings, "save-raw", setting_dng_button, "active", G_SETTINGS_BIND_DEFAULT);
|
||||
g_settings_bind(settings, "save-raw", setting_dng_button, "active",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
setting_save_dng = g_settings_get_boolean(settings, "save-raw");
|
||||
|
||||
// Listen for phosh rotation
|
||||
GDBusConnection *conn = g_application_get_dbus_connection(G_APPLICATION(app));
|
||||
GDBusConnection *conn =
|
||||
g_application_get_dbus_connection(G_APPLICATION(app));
|
||||
g_dbus_connection_signal_subscribe(
|
||||
conn,
|
||||
NULL,
|
||||
"org.gnome.Mutter.DisplayConfig",
|
||||
"MonitorsChanged",
|
||||
"/org/gnome/Mutter/DisplayConfig",
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
&on_screen_rotate,
|
||||
NULL,
|
||||
NULL);
|
||||
conn, NULL, "org.gnome.Mutter.DisplayConfig", "MonitorsChanged",
|
||||
"/org/gnome/Mutter/DisplayConfig", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
&on_screen_rotate, NULL, NULL);
|
||||
update_screen_rotation(conn);
|
||||
|
||||
// Initialize display flash
|
||||
|
@ -1000,14 +1013,13 @@ main(int argc, char *argv[])
|
|||
#ifdef RENDERDOC
|
||||
{
|
||||
void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD);
|
||||
if (mod)
|
||||
{
|
||||
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
|
||||
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&rdoc_api);
|
||||
assert(ret == 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mod) {
|
||||
pRENDERDOC_GetAPI RENDERDOC_GetAPI =
|
||||
(pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
|
||||
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2,
|
||||
(void **)&rdoc_api);
|
||||
assert(ret == 1);
|
||||
} else {
|
||||
printf("Renderdoc not found\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,8 @@ mp_pipeline_sync(MPPipeline *pipeline)
|
|||
g_mutex_init(&mutex);
|
||||
g_mutex_lock(&mutex);
|
||||
|
||||
g_main_context_invoke_full(pipeline->main_context, G_PRIORITY_LOW, (GSourceFunc)unlock_mutex, &mutex, NULL);
|
||||
g_main_context_invoke_full(pipeline->main_context, G_PRIORITY_LOW,
|
||||
(GSourceFunc)unlock_mutex, &mutex, NULL);
|
||||
g_mutex_lock(&mutex);
|
||||
g_mutex_unlock(&mutex);
|
||||
|
||||
|
|
|
@ -123,7 +123,6 @@ mp_process_pipeline_start()
|
|||
|
||||
mp_pipeline_invoke(pipeline, setup, NULL, 0);
|
||||
|
||||
|
||||
mp_zbar_pipeline_start();
|
||||
}
|
||||
|
||||
|
@ -172,7 +171,7 @@ static GLES2Debayer *gles2_debayer = NULL;
|
|||
|
||||
static GdkGLContext *context;
|
||||
|
||||
#define RENDERDOC
|
||||
// #define RENDERDOC
|
||||
|
||||
#ifdef RENDERDOC
|
||||
#include <renderdoc/app.h>
|
||||
|
@ -239,13 +238,15 @@ init_gl(MPPipeline *pipeline, GdkSurface **surface)
|
|||
int major, minor;
|
||||
gdk_gl_context_get_version(context, &major, &minor);
|
||||
|
||||
printf("Initialized %s %d.%d\n", is_es ? "OpenGL ES" : "OpenGL", major, minor);
|
||||
printf("Initialized %s %d.%d\n", is_es ? "OpenGL ES" : "OpenGL", major,
|
||||
minor);
|
||||
}
|
||||
|
||||
void
|
||||
mp_process_pipeline_init_gl(GdkSurface *surface)
|
||||
{
|
||||
mp_pipeline_invoke(pipeline, (MPPipelineCallback) init_gl, &surface, sizeof(GdkSurface *));
|
||||
mp_pipeline_invoke(pipeline, (MPPipelineCallback)init_gl, &surface,
|
||||
sizeof(GdkSurface *));
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
|
@ -269,7 +270,9 @@ process_image_for_preview(const uint8_t *image)
|
|||
assert(output_buffer != NULL);
|
||||
|
||||
#ifdef RENDERDOC
|
||||
if (rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
|
||||
if (rdoc_api) {
|
||||
rdoc_api->StartFrameCapture(NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Copy image to a GL texture. TODO: This can be avoided
|
||||
|
@ -280,11 +283,12 @@ process_image_for_preview(const uint8_t *image)
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, mode.width, mode.height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, mode.width, mode.height, 0,
|
||||
GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
|
||||
check_gl();
|
||||
|
||||
gles2_debayer_process(
|
||||
gles2_debayer, output_buffer->texture_id, input_texture);
|
||||
gles2_debayer_process(gles2_debayer, output_buffer->texture_id,
|
||||
input_texture);
|
||||
check_gl();
|
||||
|
||||
glFinish();
|
||||
|
@ -293,11 +297,14 @@ process_image_for_preview(const uint8_t *image)
|
|||
|
||||
#ifdef PROFILE_DEBAYER
|
||||
clock_t t2 = clock();
|
||||
printf("process_image_for_preview %fms\n", (float)(t2 - t1) / CLOCKS_PER_SEC * 1000);
|
||||
printf("process_image_for_preview %fms\n",
|
||||
(float)(t2 - t1) / CLOCKS_PER_SEC * 1000);
|
||||
#endif
|
||||
|
||||
#ifdef RENDERDOC
|
||||
if(rdoc_api) rdoc_api->EndFrameCapture(NULL, NULL);
|
||||
if (rdoc_api) {
|
||||
rdoc_api->EndFrameCapture(NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
mp_process_pipeline_buffer_ref(output_buffer);
|
||||
|
@ -308,27 +315,31 @@ process_image_for_preview(const uint8_t *image)
|
|||
if (captures_remaining == 1) {
|
||||
printf("Making thumbnail\n");
|
||||
|
||||
size_t size = output_buffer_width * output_buffer_height * sizeof(uint32_t);
|
||||
size_t size = output_buffer_width * output_buffer_height *
|
||||
sizeof(uint32_t);
|
||||
|
||||
uint32_t *data = g_malloc_n(size, 1);
|
||||
|
||||
glReadPixels(0, 0, output_buffer_width, output_buffer_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glReadPixels(0, 0, output_buffer_width, output_buffer_height,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
check_gl();
|
||||
|
||||
// Flip vertically
|
||||
for (size_t y = 0; y < output_buffer_height / 2; ++y) {
|
||||
for (size_t x = 0; x < output_buffer_width; ++x) {
|
||||
uint32_t tmp = data[(output_buffer_height - y - 1) * output_buffer_width + x];
|
||||
data[(output_buffer_height - y - 1) * output_buffer_width + x] = data[y * output_buffer_width + x];
|
||||
uint32_t tmp = data[(output_buffer_height - y - 1) *
|
||||
output_buffer_width +
|
||||
x];
|
||||
data[(output_buffer_height - y - 1) *
|
||||
output_buffer_width +
|
||||
x] = data[y * output_buffer_width + x];
|
||||
data[y * output_buffer_width + x] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
thumb = gdk_memory_texture_new(
|
||||
output_buffer_width,
|
||||
output_buffer_height,
|
||||
GDK_MEMORY_R8G8B8A8,
|
||||
g_bytes_new_take(data, size),
|
||||
output_buffer_width, output_buffer_height,
|
||||
GDK_MEMORY_R8G8B8A8, g_bytes_new_take(data, size),
|
||||
output_buffer_width * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
|
@ -365,16 +376,16 @@ process_image_for_capture(const uint8_t *image, int count)
|
|||
uint16_t orientation;
|
||||
if (camera_rotation == 0) {
|
||||
orientation = camera->mirrored ? ORIENTATION_TOPRIGHT :
|
||||
ORIENTATION_TOPLEFT;
|
||||
ORIENTATION_TOPLEFT;
|
||||
} else if (camera_rotation == 90) {
|
||||
orientation = camera->mirrored ? ORIENTATION_RIGHTBOT :
|
||||
ORIENTATION_LEFTBOT;
|
||||
ORIENTATION_LEFTBOT;
|
||||
} else if (camera_rotation == 180) {
|
||||
orientation = camera->mirrored ? ORIENTATION_BOTLEFT :
|
||||
ORIENTATION_BOTRIGHT;
|
||||
ORIENTATION_BOTRIGHT;
|
||||
} else {
|
||||
orientation = camera->mirrored ? ORIENTATION_LEFTTOP :
|
||||
ORIENTATION_RIGHTTOP;
|
||||
ORIENTATION_RIGHTTOP;
|
||||
}
|
||||
TIFFSetField(tif, TIFFTAG_ORIENTATION, orientation);
|
||||
TIFFSetField(tif, TIFFTAG_DATETIME, datetime);
|
||||
|
@ -415,7 +426,8 @@ process_image_for_capture(const uint8_t *image, int count)
|
|||
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0);
|
||||
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, mode.width);
|
||||
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, mode.height);
|
||||
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, mp_pixel_format_bits_per_pixel(mode.pixel_format));
|
||||
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,
|
||||
mp_pixel_format_bits_per_pixel(mode.pixel_format));
|
||||
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA);
|
||||
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||||
|
@ -429,7 +441,8 @@ process_image_for_capture(const uint8_t *image, int count)
|
|||
printf("TIFF version %d\n", TIFFLIB_VERSION);
|
||||
int whitelevel = camera->whitelevel;
|
||||
if (!whitelevel) {
|
||||
whitelevel = (1 << mp_pixel_format_pixel_depth(mode.pixel_format)) - 1;
|
||||
whitelevel =
|
||||
(1 << mp_pixel_format_pixel_depth(mode.pixel_format)) - 1;
|
||||
}
|
||||
TIFFSetField(tif, TIFFTAG_WHITELEVEL, 1, &whitelevel);
|
||||
if (camera->blacklevel) {
|
||||
|
@ -440,7 +453,12 @@ process_image_for_capture(const uint8_t *image, int count)
|
|||
printf("Writing frame to %s\n", fname);
|
||||
|
||||
for (int row = 0; row < mode.height; row++) {
|
||||
TIFFWriteScanline(tif, (void *) image + (row * mp_pixel_format_width_to_bytes(mode.pixel_format, mode.width)), row, 0);
|
||||
TIFFWriteScanline(
|
||||
tif,
|
||||
(void *)image +
|
||||
(row * mp_pixel_format_width_to_bytes(
|
||||
mode.pixel_format, mode.width)),
|
||||
row, 0);
|
||||
}
|
||||
TIFFWriteDirectory(tif);
|
||||
|
||||
|
@ -522,19 +540,14 @@ process_capture_burst(GdkTexture *thumb)
|
|||
strftime(timestamp, 30, "%Y%m%d%H%M%S", &tim);
|
||||
|
||||
if (g_get_user_special_dir(G_USER_DIRECTORY_PICTURES) != NULL) {
|
||||
sprintf(capture_fname,
|
||||
"%s/IMG%s",
|
||||
sprintf(capture_fname, "%s/IMG%s",
|
||||
g_get_user_special_dir(G_USER_DIRECTORY_PICTURES),
|
||||
timestamp);
|
||||
} else if (getenv("XDG_PICTURES_DIR") != NULL) {
|
||||
sprintf(capture_fname,
|
||||
"%s/IMG%s",
|
||||
getenv("XDG_PICTURES_DIR"),
|
||||
sprintf(capture_fname, "%s/IMG%s", getenv("XDG_PICTURES_DIR"),
|
||||
timestamp);
|
||||
} else {
|
||||
sprintf(capture_fname,
|
||||
"%s/Pictures/IMG%s",
|
||||
getenv("HOME"),
|
||||
sprintf(capture_fname, "%s/Pictures/IMG%s", getenv("HOME"),
|
||||
timestamp);
|
||||
}
|
||||
|
||||
|
@ -544,16 +557,12 @@ process_capture_burst(GdkTexture *thumb)
|
|||
}
|
||||
|
||||
// Start post-processing the captured burst
|
||||
g_print("Post process %s to %s.ext (save-dng %s)\n", burst_dir, capture_fname, save_dng_s);
|
||||
g_print("Post process %s to %s.ext (save-dng %s)\n", burst_dir,
|
||||
capture_fname, save_dng_s);
|
||||
GError *error = NULL;
|
||||
GSubprocess *proc = g_subprocess_new(
|
||||
G_SUBPROCESS_FLAGS_STDOUT_PIPE,
|
||||
&error,
|
||||
processing_script,
|
||||
burst_dir,
|
||||
capture_fname,
|
||||
save_dng_s,
|
||||
NULL);
|
||||
GSubprocess *proc = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error,
|
||||
processing_script, burst_dir,
|
||||
capture_fname, save_dng_s, NULL);
|
||||
|
||||
if (!proc) {
|
||||
g_printerr("Failed to spawn postprocess process: %s\n",
|
||||
|
@ -562,11 +571,7 @@ process_capture_burst(GdkTexture *thumb)
|
|||
}
|
||||
|
||||
g_subprocess_communicate_utf8_async(
|
||||
proc,
|
||||
NULL,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)post_process_finished,
|
||||
thumb);
|
||||
proc, NULL, NULL, (GAsyncReadyCallback)post_process_finished, thumb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -576,14 +581,15 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer)
|
|||
clock_t t1 = clock();
|
||||
#endif
|
||||
|
||||
size_t size =
|
||||
mp_pixel_format_width_to_bytes(mode.pixel_format, mode.width) *
|
||||
mode.height;
|
||||
size_t size = mp_pixel_format_width_to_bytes(mode.pixel_format, mode.width) *
|
||||
mode.height;
|
||||
uint8_t *image = malloc(size);
|
||||
memcpy(image, buffer->data, size);
|
||||
mp_io_pipeline_release_buffer(buffer->index);
|
||||
|
||||
MPZBarImage *zbar_image = mp_zbar_image_new(image, mode.pixel_format, mode.width, mode.height, camera_rotation, camera->mirrored);
|
||||
MPZBarImage *zbar_image =
|
||||
mp_zbar_image_new(image, mode.pixel_format, mode.width, mode.height,
|
||||
camera_rotation, camera->mirrored);
|
||||
mp_zbar_pipeline_process_image(mp_zbar_image_ref(zbar_image));
|
||||
|
||||
#ifdef PROFILE_PROCESS
|
||||
|
@ -678,16 +684,16 @@ on_output_changed()
|
|||
|
||||
for (size_t i = 0; i < NUM_BUFFERS; ++i) {
|
||||
glBindTexture(GL_TEXTURE_2D, output_buffers[i].texture_id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, output_buffer_width, output_buffer_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, output_buffer_width,
|
||||
output_buffer_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
gles2_debayer_configure(
|
||||
gles2_debayer,
|
||||
output_buffer_width, output_buffer_height,
|
||||
mode.width, mode.height,
|
||||
camera->rotate, camera->mirrored,
|
||||
gles2_debayer, output_buffer_width, output_buffer_height, mode.width,
|
||||
mode.height, camera->rotate, camera->mirrored,
|
||||
camera->previewmatrix[0] == 0 ? NULL : camera->previewmatrix,
|
||||
camera->blacklevel);
|
||||
}
|
||||
|
@ -695,18 +701,18 @@ on_output_changed()
|
|||
static int
|
||||
mod(int a, int b)
|
||||
{
|
||||
int r = a % b;
|
||||
return r < 0 ? r + b : r;
|
||||
int r = a % b;
|
||||
return r < 0 ? r + b : r;
|
||||
}
|
||||
|
||||
static void
|
||||
update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state)
|
||||
{
|
||||
const bool output_changed =
|
||||
!mp_camera_mode_is_equivalent(&mode, &state->mode)
|
||||
|| preview_width != state->preview_width
|
||||
|| preview_height != state->preview_height
|
||||
|| device_rotation != state->device_rotation;
|
||||
!mp_camera_mode_is_equivalent(&mode, &state->mode) ||
|
||||
preview_width != state->preview_width ||
|
||||
preview_height != state->preview_height ||
|
||||
device_rotation != state->device_rotation;
|
||||
|
||||
camera = state->camera;
|
||||
mode = state->mode;
|
||||
|
@ -756,4 +762,7 @@ mp_process_pipeline_update_state(const struct mp_process_pipeline_state *new_sta
|
|||
}
|
||||
|
||||
// GTK4 seems to require this
|
||||
void pango_fc_font_get_languages() {}
|
||||
void
|
||||
pango_fc_font_get_languages()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ static volatile int frames_received = 0;
|
|||
|
||||
static zbar_image_scanner_t *scanner;
|
||||
|
||||
static void setup(MPPipeline *pipeline, const void *data)
|
||||
static void
|
||||
setup(MPPipeline *pipeline, const void *data)
|
||||
{
|
||||
scanner = zbar_image_scanner_create();
|
||||
zbar_image_scanner_set_config(scanner, 0, ZBAR_CFG_ENABLE, 1);
|
||||
|
@ -48,29 +49,29 @@ static bool
|
|||
is_3d_code(zbar_symbol_type_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case ZBAR_EAN2:
|
||||
case ZBAR_EAN5:
|
||||
case ZBAR_EAN8:
|
||||
case ZBAR_UPCE:
|
||||
case ZBAR_ISBN10:
|
||||
case ZBAR_UPCA:
|
||||
case ZBAR_EAN13:
|
||||
case ZBAR_ISBN13:
|
||||
case ZBAR_I25:
|
||||
case ZBAR_DATABAR:
|
||||
case ZBAR_DATABAR_EXP:
|
||||
case ZBAR_CODABAR:
|
||||
case ZBAR_CODE39:
|
||||
case ZBAR_CODE93:
|
||||
case ZBAR_CODE128:
|
||||
return false;
|
||||
case ZBAR_COMPOSITE:
|
||||
case ZBAR_PDF417:
|
||||
case ZBAR_QRCODE:
|
||||
case ZBAR_SQCODE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
case ZBAR_EAN2:
|
||||
case ZBAR_EAN5:
|
||||
case ZBAR_EAN8:
|
||||
case ZBAR_UPCE:
|
||||
case ZBAR_ISBN10:
|
||||
case ZBAR_UPCA:
|
||||
case ZBAR_EAN13:
|
||||
case ZBAR_ISBN13:
|
||||
case ZBAR_I25:
|
||||
case ZBAR_DATABAR:
|
||||
case ZBAR_DATABAR_EXP:
|
||||
case ZBAR_CODABAR:
|
||||
case ZBAR_CODE39:
|
||||
case ZBAR_CODE93:
|
||||
case ZBAR_CODE128:
|
||||
return false;
|
||||
case ZBAR_COMPOSITE:
|
||||
case ZBAR_PDF417:
|
||||
case ZBAR_QRCODE:
|
||||
case ZBAR_SQCODE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +102,8 @@ map_coords(int *x, int *y, int width, int height, int rotation, bool mirrored)
|
|||
}
|
||||
|
||||
static MPZBarCode
|
||||
process_symbol(const MPZBarImage *image, int width, int height, const zbar_symbol_t *symbol)
|
||||
process_symbol(const MPZBarImage *image, int width, int height,
|
||||
const zbar_symbol_t *symbol)
|
||||
{
|
||||
if (image->rotation == 90 || image->rotation == 270) {
|
||||
int tmp = width;
|
||||
|
@ -145,13 +147,14 @@ process_symbol(const MPZBarImage *image, int width, int height, const zbar_symbo
|
|||
}
|
||||
|
||||
for (uint8_t i = 0; i < 4; ++i) {
|
||||
map_coords(&code.bounds_x[i], &code.bounds_y[i], width, height, image->rotation, image->mirrored);
|
||||
map_coords(&code.bounds_x[i], &code.bounds_y[i], width, height,
|
||||
image->rotation, image->mirrored);
|
||||
}
|
||||
|
||||
const char *data = zbar_symbol_get_data(symbol);
|
||||
unsigned int data_size = zbar_symbol_get_data_length(symbol);
|
||||
code.type = zbar_get_symbol_name(type);
|
||||
code.data = strndup(data, data_size+1);
|
||||
code.data = strndup(data, data_size + 1);
|
||||
code.data[data_size] = 0;
|
||||
|
||||
return code;
|
||||
|
@ -162,10 +165,10 @@ process_image(MPPipeline *pipeline, MPZBarImage **_image)
|
|||
{
|
||||
MPZBarImage *image = *_image;
|
||||
|
||||
assert(image->pixel_format == MP_PIXEL_FMT_BGGR8
|
||||
|| image->pixel_format == MP_PIXEL_FMT_GBRG8
|
||||
|| image->pixel_format == MP_PIXEL_FMT_GRBG8
|
||||
|| image->pixel_format == MP_PIXEL_FMT_RGGB8);
|
||||
assert(image->pixel_format == MP_PIXEL_FMT_BGGR8 ||
|
||||
image->pixel_format == MP_PIXEL_FMT_GBRG8 ||
|
||||
image->pixel_format == MP_PIXEL_FMT_GRBG8 ||
|
||||
image->pixel_format == MP_PIXEL_FMT_RGGB8);
|
||||
|
||||
// Create a grayscale image for scanning from the current preview.
|
||||
// Rotate/mirror correctly.
|
||||
|
@ -184,7 +187,8 @@ process_image(MPPipeline *pipeline, MPZBarImage **_image)
|
|||
zbar_image_t *zbar_image = zbar_image_create();
|
||||
zbar_image_set_format(zbar_image, zbar_fourcc('Y', '8', '0', '0'));
|
||||
zbar_image_set_size(zbar_image, width, height);
|
||||
zbar_image_set_data(zbar_image, data, width * height * sizeof(uint8_t), zbar_image_free_data);
|
||||
zbar_image_set_data(zbar_image, data, width * height * sizeof(uint8_t),
|
||||
zbar_image_free_data);
|
||||
|
||||
int res = zbar_scan_image(scanner, zbar_image);
|
||||
assert(res >= 0);
|
||||
|
@ -196,7 +200,8 @@ process_image(MPPipeline *pipeline, MPZBarImage **_image)
|
|||
const zbar_symbol_t *symbol = zbar_image_first_symbol(zbar_image);
|
||||
for (int i = 0; i < MIN(res, 8); ++i) {
|
||||
assert(symbol != NULL);
|
||||
result->codes[i] = process_symbol(image, width, height, symbol);
|
||||
result->codes[i] =
|
||||
process_symbol(image, width, height, symbol);
|
||||
symbol = zbar_symbol_next(symbol);
|
||||
}
|
||||
|
||||
|
@ -227,12 +232,8 @@ mp_zbar_pipeline_process_image(MPZBarImage *image)
|
|||
}
|
||||
|
||||
MPZBarImage *
|
||||
mp_zbar_image_new(uint8_t *data,
|
||||
MPPixelFormat pixel_format,
|
||||
int width,
|
||||
int height,
|
||||
int rotation,
|
||||
bool mirrored)
|
||||
mp_zbar_image_new(uint8_t *data, MPPixelFormat pixel_format, int width, int height,
|
||||
int rotation, bool mirrored)
|
||||
{
|
||||
MPZBarImage *image = malloc(sizeof(MPZBarImage));
|
||||
image->data = data;
|
||||
|
|
|
@ -21,11 +21,7 @@ void mp_zbar_pipeline_stop();
|
|||
|
||||
void mp_zbar_pipeline_process_image(MPZBarImage *image);
|
||||
|
||||
MPZBarImage *mp_zbar_image_new(uint8_t *data,
|
||||
MPPixelFormat pixel_format,
|
||||
int width,
|
||||
int height,
|
||||
int rotation,
|
||||
bool mirrored);
|
||||
MPZBarImage *mp_zbar_image_new(uint8_t *data, MPPixelFormat pixel_format, int width,
|
||||
int height, int rotation, bool mirrored);
|
||||
MPZBarImage *mp_zbar_image_ref(MPZBarImage *image);
|
||||
void mp_zbar_image_unref(MPZBarImage *image);
|
||||
|
|
|
@ -175,9 +175,9 @@ main(int argc, char *argv[])
|
|||
printf(" Failed to capture buffer\n");
|
||||
}
|
||||
|
||||
size_t num_bytes =
|
||||
mp_pixel_format_width_to_bytes(m->pixel_format, m->width) *
|
||||
m->height;
|
||||
size_t num_bytes = mp_pixel_format_width_to_bytes(
|
||||
m->pixel_format, m->width) *
|
||||
m->height;
|
||||
uint8_t *data = malloc(num_bytes);
|
||||
memcpy(data, buffer.data, num_bytes);
|
||||
|
||||
|
|
Loading…
Reference in New Issue