Add clang-format as part of CI

This commit is contained in:
Benjamin Schaaf 2021-11-12 20:27:47 +11:00 committed by Martijn Braam
parent 11b8e8600c
commit 3e1a289565
No known key found for this signature in database
GPG Key ID: C4280ACB000B060F
23 changed files with 560 additions and 452 deletions

View File

@ -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

4
clang-format.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
cd "$MESON_SOURCE_ROOT"
clang-format-12 $@

View File

@ -6,6 +6,8 @@ uniform sampler2D texture;
varying vec2 uv;
void main() {
void
main()
{
gl_FragColor = vec4(texture2D(texture, uv).rgb, 1);
}

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -4,6 +4,8 @@ precision mediump float;
uniform vec4 color;
void main() {
void
main()
{
gl_FragColor = color;
}

View File

@ -4,6 +4,8 @@ precision mediump float;
attribute vec2 vert;
void main() {
void
main()
{
gl_Position = vec4(vert, 0, 1);
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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");
}
}

View File

@ -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);

View File

@ -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()
{
}

View File

@ -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;

View File

@ -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);

View File

@ -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);