diff --git a/data/camera.ui b/data/camera.ui index d976169..83adf8e 100644 --- a/data/camera.ui +++ b/data/camera.ui @@ -238,6 +238,11 @@ + + + Save raw files + + diff --git a/data/meson.build b/data/meson.build index c0de055..2f42217 100644 --- a/data/meson.build +++ b/data/meson.build @@ -13,3 +13,9 @@ install_data('org.postmarketos.Megapixels.svg', install_data(['postprocess.sh'], install_dir: get_option('datadir') / 'megapixels/', install_mode: 'rwxr-xr-x') + +settings_schemas = ['org.postmarketos.Megapixels.gschema.xml'] +schemas_dir = get_option('prefix') / get_option('datadir') / 'glib-2.0' / 'schemas' +install_data(settings_schemas, install_dir: schemas_dir) +gnome.compile_schemas(depend_files: files(settings_schemas)) +meson.add_install_script('glib-compile-schemas', schemas_dir) diff --git a/data/org.postmarketos.Megapixels.gschema.xml b/data/org.postmarketos.Megapixels.gschema.xml new file mode 100644 index 0000000..b175f7e --- /dev/null +++ b/data/org.postmarketos.Megapixels.gschema.xml @@ -0,0 +1,15 @@ + + + + + + true + Don't throw away the .dng file after post processing + + Megapixels will write a .dng file that's passed to the post processing script + if this setting is disabled the post-process script will be told to clean it + up after processing. + + + + diff --git a/data/postprocess.sh b/data/postprocess.sh index 792b817..b032866 100755 --- a/data/postprocess.sh +++ b/data/postprocess.sh @@ -8,16 +8,22 @@ # The second argument is the filename for the final photo without # the extension, like "/home/user/Pictures/IMG202104031234" # +# The third argument is 1 or 0 for the cleanup user config. If this +# is 0 the .dng file should not be moved to the output directory +# # The post-processing script is responsible for cleaning up # temporary directory for the burst. -if [ "$#" -ne 2 ]; then - echo "Usage: $0 [burst-dir] [target-name]" +set -e + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 [burst-dir] [target-name] [save-dng]" exit 2 fi BURST_DIR="$1" TARGET_NAME="$2" +SAVE_DNG="$3" MAIN_PICTURE="$BURST_DIR"/1 @@ -92,3 +98,7 @@ fi # Clean up the temp dir containing the burst rm -rf "$BURST_DIR" +# Clean up the .dng if the user didn't want it +if [ "$SAVE_DNG" -eq "0" ]; then + rm "$TARGET_NAME.dng" +fi diff --git a/src/io_pipeline.c b/src/io_pipeline.c index 1281df3..f9bb1dc 100644 --- a/src/io_pipeline.c +++ b/src/io_pipeline.c @@ -77,6 +77,8 @@ static int preview_height; static int device_rotation; +static bool save_dng; + struct control_state { bool gain_is_manual; int gain; @@ -275,6 +277,7 @@ update_process_pipeline() .camera = camera, .mode = mode, .burst_length = burst_length, + .save_dng = save_dng, .preview_width = preview_width, .preview_height = preview_height, .device_rotation = device_rotation, @@ -531,6 +534,7 @@ update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state) preview_width = state->preview_width; preview_height = state->preview_height; device_rotation = state->device_rotation; + save_dng = state->save_dng; if (camera) { struct control_state previous_desired = desired_controls; diff --git a/src/io_pipeline.h b/src/io_pipeline.h index 62b0c8b..a8a0f2c 100644 --- a/src/io_pipeline.h +++ b/src/io_pipeline.h @@ -17,6 +17,8 @@ struct mp_io_pipeline_state { bool exposure_is_manual; int exposure; + + bool save_dng; }; void mp_io_pipeline_start(); diff --git a/src/main.c b/src/main.c index 1126ae1..97b048c 100644 --- a/src/main.c +++ b/src/main.c @@ -71,6 +71,9 @@ GtkWidget *process_spinner; GtkWidget *scanned_codes; GtkWidget *preview_top_box; GtkWidget *preview_bottom_box; +GtkWidget *setting_dng; + +GSettings *settings; int remap(int value, int input_min, int input_max, int output_min, int output_max) @@ -102,6 +105,7 @@ update_io_pipeline() .gain = gain, .exposure_is_manual = exposure_is_manual, .exposure = exposure, + .save_dng = gtk_check_button_get_active(GTK_CHECK_BUTTON(setting_dng)), }; mp_io_pipeline_update_state(&io_state); } @@ -453,6 +457,7 @@ run_capture_action(GSimpleAction *action, GVariant *param, gpointer user_data) { gtk_spinner_start(GTK_SPINNER(process_spinner)); gtk_stack_set_visible_child(GTK_STACK(open_last_stack), process_spinner); + update_io_pipeline(); mp_io_pipeline_capture(); } @@ -883,6 +888,8 @@ activate(GtkApplication *app, gpointer data) preview_top_box = GTK_WIDGET(gtk_builder_get_object(builder, "top-box")); preview_bottom_box = GTK_WIDGET(gtk_builder_get_object(builder, "bottom-box")); + setting_dng = GTK_WIDGET(gtk_builder_get_object(builder, "setting-raw")); + g_signal_connect(window, "realize", G_CALLBACK(on_realize), NULL); g_signal_connect(preview, "realize", G_CALLBACK(preview_realize), NULL); @@ -912,6 +919,10 @@ activate(GtkApplication *app, gpointer data) const char *quit_accels[] = { "q", "w", NULL }; gtk_application_set_accels_for_action(app, "app.quit", quit_accels); + // Setup settings + settings = g_settings_new("org.postmarketos.Megapixels"); + g_settings_bind (settings, "save-raw", setting_dng, "active", G_SETTINGS_BIND_DEFAULT); + // Listen for phosh rotation GDBusConnection *conn = g_application_get_dbus_connection(G_APPLICATION(app)); g_dbus_connection_signal_subscribe( diff --git a/src/process_pipeline.c b/src/process_pipeline.c index 0e4e6e9..606b714 100644 --- a/src/process_pipeline.c +++ b/src/process_pipeline.c @@ -51,6 +51,8 @@ static int gain_max; static bool exposure_is_manual; static int exposure; +static bool save_dng; + static char capture_fname[255]; static void @@ -533,9 +535,13 @@ process_capture_burst(GdkTexture *thumb) timestamp); } + char save_dng_s[2] = "0"; + if (save_dng) { + save_dng_s[0] = '1'; + } // Start post-processing the captured burst - g_print("Post process %s to %s.ext\n", burst_dir, capture_fname); + 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, @@ -543,6 +549,7 @@ process_capture_burst(GdkTexture *thumb) processing_script, burst_dir, capture_fname, + save_dng_s, NULL); if (!proc) { @@ -707,6 +714,7 @@ update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state device_rotation = state->device_rotation; burst_length = state->burst_length; + save_dng = state->save_dng; // gain_is_manual = state->gain_is_manual; gain = state->gain; diff --git a/src/process_pipeline.h b/src/process_pipeline.h index 2413d35..6902409 100644 --- a/src/process_pipeline.h +++ b/src/process_pipeline.h @@ -24,6 +24,8 @@ struct mp_process_pipeline_state { bool has_auto_focus_continuous; bool has_auto_focus_start; + + bool save_dng; }; void mp_process_pipeline_start();