app, pdb, libgimp: make the raw image importer configurable

Add "import-raw-plug-in" to gimprc, and a new procedure
gimp_register_file_handler_raw(). On startup, remove all load
procedures that are marked as "handles raw" but are not implemented by
the configured plug-in. Add the list of available plug-ins to prefs ->
import/export. Register all file-darktable procedures as handling raw.
This commit is contained in:
Michael Natterer 2017-05-04 20:35:53 +02:00
parent 7e239901dd
commit 560340e8d6
19 changed files with 348 additions and 16 deletions

View File

@ -109,6 +109,7 @@ enum
PROP_IMPORT_PROMOTE_FLOAT,
PROP_IMPORT_PROMOTE_DITHER,
PROP_IMPORT_ADD_ALPHA,
PROP_IMPORT_RAW_PLUG_IN,
/* ignored, only for backward compatibility: */
PROP_INSTALL_COLORMAP,
@ -642,6 +643,15 @@ gimp_core_config_class_init (GimpCoreConfigClass *klass)
FALSE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_PATH (object_class, PROP_IMPORT_RAW_PLUG_IN,
"import-raw-plug-in",
"Import raw plug-in",
IMPORT_RAW_PLUG_IN_BLURB,
GIMP_CONFIG_PATH_FILE,
NULL,
GIMP_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_RESTART);
/* only for backward compatibility: */
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INSTALL_COLORMAP,
"install-colormap",
@ -714,6 +724,7 @@ gimp_core_config_finalize (GObject *object)
g_free (core_config->default_tool_preset);
g_free (core_config->default_font);
g_free (core_config->plug_in_rc_path);
g_free (core_config->import_raw_plug_in);
if (core_config->default_image)
g_object_unref (core_config->default_image);
@ -935,6 +946,10 @@ gimp_core_config_set_property (GObject *object,
case PROP_IMPORT_ADD_ALPHA:
core_config->import_add_alpha = g_value_get_boolean (value);
break;
case PROP_IMPORT_RAW_PLUG_IN:
g_free (core_config->import_raw_plug_in);
core_config->import_raw_plug_in = g_value_dup_string (value);
break;
case PROP_INSTALL_COLORMAP:
case PROP_MIN_COLORS:
@ -1119,6 +1134,9 @@ gimp_core_config_get_property (GObject *object,
case PROP_IMPORT_ADD_ALPHA:
g_value_set_boolean (value, core_config->import_add_alpha);
break;
case PROP_IMPORT_RAW_PLUG_IN:
g_value_set_string (value, core_config->import_raw_plug_in);
break;
case PROP_INSTALL_COLORMAP:
case PROP_MIN_COLORS:

View File

@ -94,6 +94,7 @@ struct _GimpCoreConfig
gboolean import_promote_float;
gboolean import_promote_dither;
gboolean import_add_alpha;
gchar *import_raw_plug_in;
};
struct _GimpCoreConfigClass

View File

@ -195,6 +195,9 @@ _("When promoting imported images to floating point precision, also add " \
#define IMPORT_ADD_ALPHA_BLURB \
_("Add an alpha channel to all layers of imported images.")
#define IMPORT_RAW_PLUG_IN_BLURB \
_("Which plug-in to use for importing raw digital camera files.")
#define INITIAL_ZOOM_TO_FIT_BLURB \
_("When enabled, this will ensure that the full image is visible after a " \
"file is opened, otherwise it will be displayed with a scale of 1:1.")

View File

@ -34,6 +34,8 @@
#include "core/gimp.h"
#include "core/gimptemplate.h"
#include "plug-in/gimppluginmanager.h"
#include "widgets/gimpaction-history.h"
#include "widgets/gimpcolorpanel.h"
#include "widgets/gimpcontainercombobox.h"
@ -47,6 +49,7 @@
#include "widgets/gimpiconsizescale.h"
#include "widgets/gimpmessagebox.h"
#include "widgets/gimpmessagedialog.h"
#include "widgets/gimppluginview.h"
#include "widgets/gimpprefsbox.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpstrokeeditor.h"
@ -95,6 +98,8 @@ static void prefs_color_management_reset (GtkWidget *widget,
static void prefs_dialog_defaults_reset (GtkWidget *widget,
GObject *config);
static void prefs_import_raw_procedure_callback (GtkWidget *widget,
GObject *config);
static void prefs_resolution_source_callback (GtkWidget *widget,
GObject *config);
static void prefs_resolution_calibrate_callback (GtkWidget *widget,
@ -486,6 +491,21 @@ prefs_template_select_callback (GimpContainerView *view,
}
}
static void
prefs_import_raw_procedure_callback (GtkWidget *widget,
GObject *config)
{
gchar *raw_plug_in;
raw_plug_in = gimp_plug_in_view_get_plug_in (GIMP_PLUG_IN_VIEW (widget));
g_object_set (config,
"import-raw-plug-in", raw_plug_in,
NULL);
g_free (raw_plug_in);
}
static void
prefs_resolution_source_callback (GtkWidget *widget,
GObject *config)
@ -1298,8 +1318,9 @@ prefs_dialog_new (Gimp *gimp,
NULL,
&top_iter);
/* Import Policies */
vbox2 = prefs_frame_new (_("Import Policies"),
GTK_CONTAINER (vbox), TRUE);
GTK_CONTAINER (vbox), FALSE);
button = prefs_check_button_add (object, "import-promote-float",
_("Promote imported images to "
@ -1321,6 +1342,32 @@ prefs_dialog_new (Gimp *gimp,
_("Color profile policy:"),
GTK_TABLE (table), 0, NULL);
/* Raw Image Importer */
vbox2 = prefs_frame_new (_("Raw Image Importer"),
GTK_CONTAINER (vbox), TRUE);
{
GtkWidget *scrolled_window;
GtkWidget *view;
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (vbox2), scrolled_window, TRUE, TRUE, 0);
gtk_widget_show (scrolled_window);
view = gimp_plug_in_view_new (gimp->plug_in_manager->raw_load_procs);
gimp_plug_in_view_set_plug_in (GIMP_PLUG_IN_VIEW (view),
core_config->import_raw_plug_in);
gtk_container_add (GTK_CONTAINER (scrolled_window), view);
gtk_widget_show (view);
g_signal_connect (view, "changed",
G_CALLBACK (prefs_import_raw_procedure_callback),
config);
}
/****************/
/* Playground */

View File

@ -561,6 +561,33 @@ register_file_handler_uri_invoker (GimpProcedure *procedure,
error ? *error : NULL);
}
static GimpValueArray *
register_file_handler_raw_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
const gchar *procedure_name;
procedure_name = g_value_get_string (gimp_value_array_index (args, 0));
if (success)
{
gchar *canonical = gimp_canonicalize_identifier (procedure_name);
success = gimp_plug_in_manager_register_handles_raw (gimp->plug_in_manager,
canonical);
g_free (canonical);
}
return gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
}
static GimpValueArray *
register_thumbnail_loader_invoker (GimpProcedure *procedure,
Gimp *gimp,
@ -1041,6 +1068,30 @@ register_fileops_procs (GimpPDB *pdb)
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-register-file-handler-raw
*/
procedure = gimp_procedure_new (register_file_handler_raw_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-register-file-handler-raw");
gimp_procedure_set_static_strings (procedure,
"gimp-register-file-handler-raw",
"Registers a file handler procedure as capable of handling raw camera files.",
"Registers a file handler procedure as capable of handling raw digital camera files. Use this procedure only to register raw load handlers, calling it on a save handler will generate an error.",
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2017",
NULL);
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("procedure-name",
"procedure name",
"The name of the procedure to enable raw handling for.",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-register-thumbnail-loader
*/

View File

@ -28,7 +28,7 @@
#include "internal-procs.h"
/* 810 procedures registered total */
/* 811 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)

View File

@ -209,6 +209,31 @@ gimp_plug_in_manager_register_handles_uri (GimpPlugInManager *manager,
return TRUE;
}
gboolean
gimp_plug_in_manager_register_handles_raw (GimpPlugInManager *manager,
const gchar *name)
{
GimpPlugInProcedure *file_proc;
GSList *list;
g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
g_return_val_if_fail (name != NULL, FALSE);
if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
list = manager->current_plug_in->plug_in_def->procedures;
else
list = manager->plug_in_procedures;
file_proc = gimp_plug_in_procedure_find (list, name);
if (! file_proc)
return FALSE;
gimp_plug_in_procedure_set_handles_raw (file_proc);
return TRUE;
}
gboolean
gimp_plug_in_manager_register_thumb_loader (GimpPlugInManager *manager,
const gchar *load_proc,

View File

@ -38,6 +38,9 @@ gboolean gimp_plug_in_manager_register_mime_type (GimpPlugInManager *manage
gboolean gimp_plug_in_manager_register_handles_uri (GimpPlugInManager *manager,
const gchar *name);
gboolean gimp_plug_in_manager_register_handles_raw (GimpPlugInManager *manager,
const gchar *name);
gboolean gimp_plug_in_manager_register_thumb_loader (GimpPlugInManager *manager,
const gchar *load_proc,
const gchar *thumb_proc);

View File

@ -77,6 +77,7 @@ static void gimp_plug_in_manager_add_from_rc (GimpPlugInManager *man
static void gimp_plug_in_manager_add_to_db (GimpPlugInManager *manager,
GimpContext *context,
GimpPlugInProcedure *proc);
static void gimp_plug_in_manager_sort_file_procs (GimpPlugInManager *manager);
static gint gimp_plug_in_manager_file_proc_compare (gconstpointer a,
gconstpointer b,
gpointer data);
@ -184,16 +185,8 @@ gimp_plug_in_manager_restore (GimpPlugInManager *manager,
gimp_plug_in_manager_add_to_db (manager, context, list->data);
}
/* sort the load, save and export procedures */
manager->load_procs =
g_slist_sort_with_data (manager->load_procs,
gimp_plug_in_manager_file_proc_compare, manager);
manager->save_procs =
g_slist_sort_with_data (manager->save_procs,
gimp_plug_in_manager_file_proc_compare, manager);
manager->export_procs =
g_slist_sort_with_data (manager->export_procs,
gimp_plug_in_manager_file_proc_compare, manager);
/* sort the load, save and export procedures, make the raw handler list */
gimp_plug_in_manager_sort_file_procs (manager);
gimp_plug_in_manager_run_extensions (manager, context, status_callback);
@ -798,6 +791,96 @@ gimp_plug_in_manager_add_to_db (GimpPlugInManager *manager,
}
}
static void
gimp_plug_in_manager_sort_file_procs (GimpPlugInManager *manager)
{
GimpCoreConfig *config = manager->gimp->config;
GFile *config_plug_in = NULL;
GFile *raw_plug_in = NULL;
GSList *list;
manager->load_procs =
g_slist_sort_with_data (manager->load_procs,
gimp_plug_in_manager_file_proc_compare, manager);
manager->save_procs =
g_slist_sort_with_data (manager->save_procs,
gimp_plug_in_manager_file_proc_compare, manager);
manager->export_procs =
g_slist_sort_with_data (manager->export_procs,
gimp_plug_in_manager_file_proc_compare, manager);
if (config->import_raw_plug_in)
config_plug_in = gimp_file_new_for_config_path (config->import_raw_plug_in,
NULL);
/* make the list of raw loaders, and remember the one configured in
* config if found
*/
for (list = manager->load_procs; list; list = g_slist_next (list))
{
GimpPlugInProcedure *file_proc = list->data;
if (file_proc->handles_raw)
{
GFile *file;
manager->raw_load_procs = g_slist_append (manager->raw_load_procs,
file_proc);
file = gimp_plug_in_procedure_get_file (file_proc);
if (! raw_plug_in &&
config_plug_in &&
g_file_equal (config_plug_in, file))
{
raw_plug_in = file;
}
}
}
if (config_plug_in)
g_object_unref (config_plug_in);
/* if no raw loader was configured, or the configured raw loader
* wasn't found, default to the first loader, if any
*/
if (! raw_plug_in && manager->raw_load_procs)
{
gchar *path;
raw_plug_in =
gimp_plug_in_procedure_get_file (manager->raw_load_procs->data);
path = gimp_file_get_config_path (raw_plug_in, NULL);
g_object_set (config,
"import-raw-plug-in", path,
NULL);
g_free (path);
}
/* finally, remove all raw loaders except the configured one from
* the list of load_procs
*/
list = manager->load_procs;
while (list)
{
GimpPlugInProcedure *file_proc = list->data;
list = g_slist_next (list);
if (file_proc->handles_raw &&
! g_file_equal (gimp_plug_in_procedure_get_file (file_proc),
raw_plug_in))
{
manager->load_procs = g_slist_remove (manager->load_procs,
file_proc);
}
}
}
static gint
gimp_plug_in_manager_file_proc_compare (gconstpointer a,
gconstpointer b,

View File

@ -150,6 +150,12 @@ gimp_plug_in_manager_finalize (GObject *object)
manager->export_procs = NULL;
}
if (manager->raw_load_procs)
{
g_slist_free (manager->raw_load_procs);
manager->raw_load_procs = NULL;
}
if (manager->plug_in_procedures)
{
g_slist_free_full (manager->plug_in_procedures,

View File

@ -47,6 +47,7 @@ struct _GimpPlugInManager
GSList *load_procs;
GSList *save_procs;
GSList *export_procs;
GSList *raw_load_procs;
GSList *menu_branches;
GSList *locale_domains;

View File

@ -1111,6 +1111,14 @@ gimp_plug_in_procedure_set_handles_uri (GimpPlugInProcedure *proc)
proc->handles_uri = TRUE;
}
void
gimp_plug_in_procedure_set_handles_raw (GimpPlugInProcedure *proc)
{
g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
proc->handles_raw = TRUE;
}
void
gimp_plug_in_procedure_set_thumb_loader (GimpPlugInProcedure *proc,
const gchar *thumb_loader)

View File

@ -61,6 +61,7 @@ struct _GimpPlugInProcedure
gchar *magics;
gchar *mime_type;
gboolean handles_uri;
gboolean handles_raw;
GSList *extensions_list;
GSList *prefixes_list;
GSList *magics_list;
@ -120,6 +121,7 @@ void gimp_plug_in_procedure_set_file_proc (GimpPlugInProcedure *pro
void gimp_plug_in_procedure_set_mime_type (GimpPlugInProcedure *proc,
const gchar *mime_ype);
void gimp_plug_in_procedure_set_handles_uri (GimpPlugInProcedure *proc);
void gimp_plug_in_procedure_set_handles_raw (GimpPlugInProcedure *proc);
void gimp_plug_in_procedure_set_thumb_loader (GimpPlugInProcedure *proc,
const gchar *thumbnailer);

View File

@ -40,7 +40,7 @@
#include "gimp-intl.h"
#define PLUG_IN_RC_FILE_VERSION 3
#define PLUG_IN_RC_FILE_VERSION 4
/*
@ -92,6 +92,7 @@ enum
MAGIC,
MIME_TYPE,
HANDLES_URI,
HANDLES_RAW,
THUMB_LOADER
};
@ -157,6 +158,8 @@ plug_in_rc_parse (Gimp *gimp,
"mime-type", GINT_TO_POINTER (MIME_TYPE));
g_scanner_scope_add_symbol (scanner, LOAD_PROC,
"handles-uri", GINT_TO_POINTER (HANDLES_URI));
g_scanner_scope_add_symbol (scanner, LOAD_PROC,
"handles-raw", GINT_TO_POINTER (HANDLES_RAW));
g_scanner_scope_add_symbol (scanner, LOAD_PROC,
"thumb-loader", GINT_TO_POINTER (THUMB_LOADER));
@ -603,7 +606,8 @@ plug_in_file_proc_deserialize (GScanner *scanner,
if (! gimp_scanner_parse_string_no_validate (scanner, &value))
return G_TOKEN_STRING;
}
else if (symbol != HANDLES_URI)
else if (symbol != HANDLES_URI &&
symbol != HANDLES_RAW)
{
if (! gimp_scanner_parse_string (scanner, &value))
return G_TOKEN_STRING;
@ -635,6 +639,10 @@ plug_in_file_proc_deserialize (GScanner *scanner,
gimp_plug_in_procedure_set_handles_uri (proc);
break;
case HANDLES_RAW:
gimp_plug_in_procedure_set_handles_raw (proc);
break;
case THUMB_LOADER:
gimp_plug_in_procedure_set_thumb_loader (proc, value);
g_free (value);
@ -932,6 +940,12 @@ plug_in_rc_write (GSList *plug_in_defs,
gimp_config_writer_close (writer);
}
if (proc->handles_raw && ! proc->image_types)
{
gimp_config_writer_open (writer, "handles-raw");
gimp_config_writer_close (writer);
}
if (proc->thumb_loader)
{
gimp_config_writer_open (writer, "thumb-loader");

View File

@ -763,6 +763,7 @@ EXPORTS
gimp_read_expect_msg
gimp_rect_select
gimp_register_file_handler_mime
gimp_register_file_handler_raw
gimp_register_file_handler_uri
gimp_register_load_handler
gimp_register_magic_load_handler

View File

@ -434,6 +434,40 @@ gimp_register_file_handler_uri (const gchar *procedure_name)
return success;
}
/**
* gimp_register_file_handler_raw:
* @procedure_name: The name of the procedure to enable raw handling for.
*
* Registers a file handler procedure as capable of handling raw camera
* files.
*
* Registers a file handler procedure as capable of handling raw
* digital camera files. Use this procedure only to register raw load
* handlers, calling it on a save handler will generate an error.
*
* Returns: TRUE on success.
*
* Since: 2.10
**/
gboolean
gimp_register_file_handler_raw (const gchar *procedure_name)
{
GimpParam *return_vals;
gint nreturn_vals;
gboolean success = TRUE;
return_vals = gimp_run_procedure ("gimp-register-file-handler-raw",
&nreturn_vals,
GIMP_PDB_STRING, procedure_name,
GIMP_PDB_END);
success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
gimp_destroy_params (return_vals, nreturn_vals);
return success;
}
/**
* gimp_register_thumbnail_loader:
* @load_proc: The name of the procedure the thumbnail loader with.

View File

@ -62,6 +62,7 @@ gboolean gimp_register_save_handler (const gchar *procedure_name,
gboolean gimp_register_file_handler_mime (const gchar *procedure_name,
const gchar *mime_type);
gboolean gimp_register_file_handler_uri (const gchar *procedure_name);
gboolean gimp_register_file_handler_raw (const gchar *procedure_name);
gboolean gimp_register_thumbnail_loader (const gchar *load_proc,
const gchar *thumb_proc);

View File

@ -33,7 +33,9 @@
#include "file-formats.h"
#define LOAD_THUMB_PROC "file-raw-load-thumb"
#define LOAD_THUMB_PROC "file-darktable-load-thumb"
static void query (void);
static void run (const gchar *name,
@ -164,6 +166,7 @@ query (void)
gimp_register_file_handler_mime (format->load_proc,
format->mime_type);
gimp_register_file_handler_raw (format->load_proc);
gimp_register_magic_load_handler (format->load_proc,
format->extensions,
"",

View File

@ -617,6 +617,36 @@ CODE
);
}
sub register_file_handler_raw {
$blurb = 'Registers a file handler procedure as capable of handling raw camera files.';
$help = <<'HELP';
Registers a file handler procedure as capable of handling raw digital
camera files. Use this procedure only to register raw load handlers,
calling it on a save handler will generate an error.
HELP
&mitch_pdb_misc('2017', '2.10');
@inargs = (
{ name => 'procedure_name', type => 'string', non_empty => 1,
desc => "The name of the procedure to enable raw handling for." }
);
%invoke = (
code => <<'CODE'
{
gchar *canonical = gimp_canonicalize_identifier (procedure_name);
success = gimp_plug_in_manager_register_handles_raw (gimp->plug_in_manager,
canonical);
g_free (canonical);
}
CODE
);
}
sub register_thumbnail_loader {
$blurb = 'Associates a thumbnail loader with a file load procedure.';
@ -675,9 +705,10 @@ CODE
register_save_handler
register_file_handler_mime
register_file_handler_uri
register_file_handler_raw
register_thumbnail_loader);
%exports = (app => [@procs], lib => [@procs[0..3,5..11]]);
%exports = (app => [@procs], lib => [@procs[0..3,5..12]]);
$desc = 'File Operations';
$doc_title = 'gimpfileops';