81#ifdef GDK_WINDOWING_QUARTZ
84#include <gdk/gdkkeysyms.h>
95#define EXPORT_MAX_IMAGE_SIZE UINT16_MAX
96#define CONFIG_PREFIX "plugins/lighttable/export/"
134#define INCH_TO_CM (2.54f)
138 const int dpi = atoi(gtk_entry_get_text(GTK_ENTRY(self->
print_dpi)));
139 return ((
float)pix *
INCH_TO_CM) / (float)dpi;
144 const int dpi = atoi(gtk_entry_get_text(GTK_ENTRY(self->
print_dpi)));
145 return (
float)pix / (float)dpi;
150 const int dpi = atoi(gtk_entry_get_text(GTK_ENTRY(self->
print_dpi)));
156 const int dpi = atoi(gtk_entry_get_text(GTK_ENTRY(self->
print_dpi)));
157 return ceilf(inch * (
float)dpi);
208 static const char *
v[] = {
"special", NULL};
229 gtk_widget_set_sensitive(GTK_WIDGET(
d->export_button), has_act_on && format_index != -1 && storage_index != -1);
251 double num = 1.0, denum = 1.0;
256 gchar *pdiv = strchr(scale_str,
'/');
258 gchar scale_buf[64] =
"";
263 sprintf(_str,
"%d", (
int) num);
264 g_strlcat(scale_buf, _str,
sizeof(scale_buf));
268 g_strlcat(scale_buf, scale_str,
sizeof(scale_buf));
271 else if(pdiv-scale_str == 0)
273 if(
_is_int(denum) && denum > 0.0)
275 sprintf(_str,
"%d", (
int) denum);
276 g_strlcat(scale_buf, _str,
sizeof(scale_buf));
280 g_strlcat(scale_buf,
"1/",
sizeof(scale_buf));
281 g_strlcat(scale_buf, pdiv+1,
sizeof(scale_buf));
288 sprintf(_str,
"%d", (
int) num);
289 g_strlcat(scale_buf, _str,
sizeof(scale_buf));
293 g_strlcat(scale_buf, scale_str,
sizeof(scale_buf));
295 g_strlcat(scale_buf,
"/",
sizeof(scale_buf));
296 if(
_is_int(denum) && denum > 0.0)
298 sprintf(_str,
"%d", (
int) denum);
299 g_strlcat(scale_buf, _str,
sizeof(scale_buf));
303 g_strlcat(scale_buf, pdiv+1,
sizeof(scale_buf));
316 char style[128] = { 0 };
325 if(format_index == -1)
330 if(storage_index == -1)
336 char *confirm_message = NULL;
338 if(mstorage->ask_user_confirmation)
339 confirm_message = mstorage->ask_user_confirmation(mstorage);
343 GtkWidget *dialog = gtk_message_dialog_new(
344 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
345 "%s", confirm_message);
346#ifdef GDK_WINDOWING_QUARTZ
350 gtk_window_set_title(GTK_WINDOW(dialog), _(
"export to disk"));
351 const gint
res = gtk_dialog_run(GTK_DIALOG(dialog));
352 gtk_widget_destroy(dialog);
355 if(
res != GTK_RESPONSE_YES)
369 g_strlcpy(style, tmp,
sizeof(style));
378 style, icc_type, icc_filename, icc_intent,
d->metadata_export);
388 const char *validSign =
",.0123456789";
389 const gchar *
value = gtk_entry_get_text(spin);
391 const int len =
sizeof(
value);
392 int i, j = 0, idec = 0, idiv = 0, pdiv = 0;
393 char new_value[30] =
"";
395 for (
i = 0;
i < len;
i++)
397 char *val = strchr(validSign,
value[
i]);
404 new_value[j++] =
'1';
408 if(atof(
value) == 0.0)
414 new_value[j++] =
'/';
419 else if((val[0] ==
'.') || (val[0] ==
','))
423 if((
i == 0) || (
i == pdiv))
425 new_value[j++] =
'0';
430 new_value[j++] =
value[
i];
440 new_value[j++] =
value[
i];
444 gtk_entry_set_text(spin, new_value);
447static void _width_changed(GtkEditable *entry, gpointer user_data);
452 if(event->button == 2)
456 gtk_entry_set_text(GTK_ENTRY(spin),
"1");
468 if(event->button == 2)
472 gtk_entry_set_text(GTK_ENTRY(spin),
"0");
473 g_signal_handlers_unblock_by_func(spin,
_width_changed, user_data);
483 if(event->button == 2)
487 gtk_entry_set_text(GTK_ENTRY(spin),
"0");
502 gtk_widget_hide(
d->size_in_px);
506 gtk_widget_show(
d->size_in_px);
507 gchar size_in_px_txt[120];
508 snprintf(size_in_px_txt,
sizeof(size_in_px_txt) /
sizeof(size_in_px_txt[0]), _(
"which is equal to %s \303\227 %s px"),
509 gtk_entry_get_text(GTK_ENTRY(
d->width)), gtk_entry_get_text(GTK_ENTRY(
d->height)));
510 gtk_label_set_text(GTK_LABEL(
d->size_in_px), size_in_px_txt);
516 gchar *max_width_char = g_strdup_printf(
"%d", max_width);
517 gchar *max_height_char = g_strdup_printf(
"%d", max_height);
520 gtk_entry_set_text(GTK_ENTRY(
d->width), max_width_char);
521 gtk_entry_set_text(GTK_ENTRY(
d->height), max_height_char);
542 gtk_label_set_text(GTK_LABEL(self->
unit_label),
595 if(mformat) mformat->gui_reset(mformat);
597 if(mstorage) mstorage->gui_reset(mstorage);
611 module = (dt_imageio_module_format_t *)it->data;
618 gtk_widget_hide(
d->format_extra_container);
621 else if(module->widget)
623 gtk_widget_show_all(
d->format_extra_container);
624 gtk_stack_set_visible_child(GTK_STACK(
d->format_extra_container), module->widget);
628 gtk_widget_hide(
d->format_extra_container);
642 const gboolean support_layers = (
module->flags(NULL) & FORMAT_FLAGS_SUPPORT_LAYERS) == FORMAT_FLAGS_SUPPORT_LAYERS;
643 const gboolean is_enabled = gtk_widget_get_sensitive(
d->export_masks);
644 if(support_layers && !is_enabled)
648 gtk_widget_set_sensitive(GTK_WIDGET(
d->export_masks),
TRUE);
651 else if(!support_layers && is_enabled)
657 gtk_widget_set_sensitive(GTK_WIDGET(
d->export_masks),
FALSE);
677 if(storage && format)
679 uint32_t fw, fh, sw, sh;
680 fw = fh = sw = sh = 0;
681 storage->dimension(storage, NULL, &sw, &sh);
682 format->dimension(format, NULL, &fw, &fh);
684 if(sw == 0 || fw == 0)
685 *
width = sw > fw ? sw : fw;
687 *
width = sw < fw ? sw : fw;
689 if(sh == 0 || fh == 0)
690 *
height = sh > fh ? sh : fh;
692 *
height = sh < fh ? sh : fh;
699 uint32_t
width = atoi(gtk_entry_get_text(GTK_ENTRY(
d->width)));
700 uint32_t
height = atoi(gtk_entry_get_text(GTK_ENTRY(
d->height)));
701 if(
width >
d->max_allowed_width ||
height >
d->max_allowed_height)
711 uint32_t max_w = 0, max_h = 0;
736 gtk_widget_hide(
d->storage_extra_container);
739 else if(module->widget)
741 gtk_widget_show_all(
d->storage_extra_container);
742 gtk_stack_set_visible_child(GTK_STACK(
d->storage_extra_container),module->widget);
746 gtk_widget_hide(
d->storage_extra_container);
754 uint32_t w = 0, h = 0;
755 module->recommended_dimension(module, NULL, &w, &h);
761 if(w > cw || w == 0) w = cw;
762 if(h >
ch || h == 0) h =
ch;
846 const int dpi = atoi(gtk_entry_get_text(GTK_ENTRY(self->
print_dpi)));
852 gchar *pwidth = g_strdup_printf(
"%.2f", p_width);
853 gchar *pheight = g_strdup_printf(
"%.2f", p_height);
854 gchar *pdpi = g_strdup_printf(
"%d", dpi);
855 gtk_entry_set_text(GTK_ENTRY(self->
print_width), pwidth);
856 gtk_entry_set_text(GTK_ENTRY(self->
print_height), pheight);
857 gtk_entry_set_text(GTK_ENTRY(self->
print_dpi), pdpi);
868 const float p_width = atof(gtk_entry_get_text(GTK_ENTRY(self->
print_width)));
869 const float p_height = atof(gtk_entry_get_text(GTK_ENTRY(self->
print_height)));
878 gchar *pwidth = g_strdup_printf(
"%d",
width);
879 gchar *pheight = g_strdup_printf(
"%d",
height);
880 gtk_entry_set_text(GTK_ENTRY(self->
width), pwidth);
881 gtk_entry_set_text(GTK_ENTRY(self->
height), pheight);
892 const uint32_t
width = atoi(gtk_entry_get_text(GTK_ENTRY(
d->width)));
902 const float p_width = atof(gtk_entry_get_text(GTK_ENTRY(
d->print_width)));
907 gchar *pwidth = g_strdup_printf(
"%d",
width);
908 gtk_entry_set_text(GTK_ENTRY(
d->width), pwidth);
919 const uint32_t
height = atoi(gtk_entry_get_text(GTK_ENTRY(
d->height)));
929 const float p_height = atof(gtk_entry_get_text(GTK_ENTRY(
d->print_height)));
934 gchar *pheight = g_strdup_printf(
"%d",
height);
935 gtk_entry_set_text(GTK_ENTRY(
d->height), pheight);
946 const int dpi = atoi(gtk_entry_get_text(GTK_ENTRY(
d->print_dpi)));
957 const char *
key = (
const char *)user_data;
995 gboolean empty =
TRUE;
999 if(storage->supported(storage, format))
1006 gtk_widget_set_sensitive(GTK_WIDGET(
d->format), !empty);
1023 gtk_container_add(GTK_CONTAINER(
d->storage_extra_container), module->widget);
1038 for(
const GList *st_iter = styles; st_iter; st_iter = g_list_next(st_iter))
1053 const gboolean ondisk =
name && !g_strcmp0(
name, _(
"file on disk"));
1059 GtkWidget *mi = gtk_menu_item_new_with_label(_(
"preferences..."));
1061 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1068 self->
data = (
void *)
d;
1079 d->storage_extra_container = gtk_stack_new();
1080 gtk_stack_set_homogeneous(GTK_STACK(
d->storage_extra_container),
FALSE);
1081 gtk_box_pack_start(GTK_BOX(self->
widget),
d->storage_extra_container,
FALSE,
TRUE, 0);
1088 gtk_container_add(GTK_CONTAINER(
d->storage_extra_container), module->widget);
1095 g_signal_connect(G_OBJECT(
d->storage),
"value-changed", G_CALLBACK(
_storage_changed), (gpointer)
d);
1103 g_signal_connect(G_OBJECT(
d->format),
"value-changed", G_CALLBACK(
_format_changed), (gpointer)
d);
1106 d->format_extra_container = gtk_stack_new();
1107 gtk_stack_set_homogeneous(GTK_STACK(
d->format_extra_container),
FALSE);
1108 gtk_box_pack_start(GTK_BOX(self->
widget),
d->format_extra_container,
FALSE,
TRUE, 0);
1115 gtk_container_add(GTK_CONTAINER(
d->format_extra_container), module->widget);
1123 _(
"Choose a method for setting the output size.\n"
1124 "The width and height specified define the bounding box\n"
1125 "in which the image will be proportionnaly fitted.\n"),
1128 N_(
"in pixels (for file)"),
1129 N_(
"in cm (for print)"),
1130 N_(
"in inch (for print)"),
1131 N_(
"by scale (for file)"),
1132 N_(
"original resolution"));
1134 d->print_width = gtk_entry_new();
1136 gtk_widget_set_tooltip_text(
d->print_width, _(
"maximum output width limit.\n"
1137 "click middle mouse button to reset to 0."));
1138 gtk_entry_set_width_chars(GTK_ENTRY(
d->print_width), 5);
1139 d->print_height = gtk_entry_new();
1141 gtk_widget_set_tooltip_text(
d->print_height, _(
"maximum output height limit.\n"
1142 "click middle mouse button to reset to 0."));
1143 gtk_entry_set_width_chars(GTK_ENTRY(
d->print_height), 5);
1144 d->print_dpi = gtk_entry_new();
1146 gtk_widget_set_tooltip_text(
d->print_dpi, _(
"resolution in dot per inch"));
1147 gtk_entry_set_width_chars(GTK_ENTRY(
d->print_dpi), 4);
1149 gtk_entry_set_text(GTK_ENTRY(
d->print_dpi), dpi);
1152 d->width = gtk_entry_new();
1154 gtk_widget_set_tooltip_text(
d->width, _(
"maximum output width limit.\n"
1155 "click middle mouse button to reset to 0."));
1156 gtk_entry_set_width_chars(GTK_ENTRY(
d->width), 5);
1157 d->height = gtk_entry_new();
1159 gtk_widget_set_tooltip_text(
d->height, _(
"maximum output height limit.\n"
1160 "click middle mouse button to reset to 0."));
1161 gtk_entry_set_width_chars(GTK_ENTRY(
d->height), 5);
1163 gtk_widget_add_events(
d->width, GDK_BUTTON_PRESS_MASK);
1164 gtk_widget_add_events(
d->height, GDK_BUTTON_PRESS_MASK);
1167 d->print_size = gtk_flow_box_new();
1168 gtk_flow_box_set_max_children_per_line(GTK_FLOW_BOX(
d->print_size), 5);
1169 gtk_flow_box_set_column_spacing (GTK_FLOW_BOX(
d->print_size), 3);
1170 gtk_container_add(GTK_CONTAINER(
d->print_size),
d->print_width);
1171 gtk_container_add(GTK_CONTAINER(
d->print_size), gtk_label_new(_(
"x")));
1172 gtk_container_add(GTK_CONTAINER(
d->print_size),
d->print_height);
1173 d->unit_label = gtk_label_new(_(
"cm"));
1174 gtk_container_add(GTK_CONTAINER(
d->print_size),
d->unit_label);
1175 GtkBox *dpi_box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL,
DT_GUI_BOX_SPACING));
1176 gtk_box_pack_start(dpi_box, gtk_label_new(_(
"@")),
FALSE,
FALSE, 0);
1177 gtk_box_pack_start(dpi_box,
d->print_dpi,
TRUE,
TRUE, 0);
1178 gtk_box_pack_start(dpi_box, gtk_label_new(_(
"dpi")),
FALSE,
FALSE, 0);
1179 gtk_container_add(GTK_CONTAINER(
d->print_size), GTK_WIDGET(dpi_box));
1182 d->px_size = gtk_flow_box_new();
1183 gtk_flow_box_set_max_children_per_line(GTK_FLOW_BOX(
d->px_size), 3);
1184 gtk_flow_box_set_column_spacing (GTK_FLOW_BOX(
d->px_size), 3);
1185 gtk_container_add(GTK_CONTAINER(
d->px_size),
d->width);
1186 gtk_container_add(GTK_CONTAINER(
d->px_size), gtk_label_new(_(
"x")));
1187 GtkBox *px_box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL,
DT_GUI_BOX_SPACING));
1188 gtk_box_pack_start(px_box,
d->height,
TRUE,
TRUE, 0);
1189 gtk_box_pack_start(px_box, gtk_label_new(_(
"px")),
FALSE,
FALSE, 0);
1190 gtk_container_add(GTK_CONTAINER(
d->px_size), GTK_WIDGET(px_box));
1193 d->scale = gtk_entry_new();
1195 gtk_entry_set_width_chars(GTK_ENTRY(
d->scale), 5);
1197 gtk_widget_set_tooltip_text(
d->scale, _(
"it can be an integer, decimal number or simple fraction.\n"
1198 "zero or empty values are equal to 1.\n"
1199 "click middle mouse button to reset to 1."));
1200 gtk_widget_set_halign(GTK_WIDGET(
d->scale), GTK_ALIGN_END);
1201 gtk_widget_add_events(
d->scale, GDK_BUTTON_PRESS_MASK);
1203 d->size_in_px = gtk_label_new(
"");
1204 gtk_label_set_ellipsize(GTK_LABEL(
d->size_in_px), PANGO_ELLIPSIZE_START);
1205 gtk_widget_set_sensitive(GTK_WIDGET(
d->size_in_px),
FALSE);
1207 gtk_widget_set_halign(GTK_WIDGET(
d->scale), GTK_ALIGN_FILL);
1208 gtk_widget_set_halign(GTK_WIDGET(
d->size_in_px), GTK_ALIGN_END);
1210 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->dimensions_type),
FALSE,
FALSE, 0);
1211 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->px_size),
FALSE,
FALSE, 0);
1212 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->print_size),
FALSE,
FALSE, 0);
1213 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->scale),
FALSE,
FALSE, 0);
1214 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->size_in_px),
FALSE,
FALSE, 0);
1220 gtk_widget_set_tooltip_text(
d->export_masks, _(
"store masks as layers in exported images. only works for some formats."));
1221 gtk_box_pack_start(GTK_BOX(self->
widget),
d->export_masks,
FALSE,
TRUE, 0);
1236 for(
size_t k = 0;
k < n_out_profiles;
k++)
1242 char *system_profile_dir = g_build_filename(datadir,
"color",
"out", NULL);
1243 char *user_profile_dir = g_build_filename(confdir,
"color",
"out", NULL);
1244 char *
tooltip = g_strdup_printf(_(
1245 "RGB color space used to encode the output files.\n"
1246 "\"same as original\" exports to the same space as the original\n"
1247 "picture, which is linear sensor RGB for raw pictures.\n"
1248 "sRGB is recommended in most cases.\n"
1249 "You can use custom color spaces defined\n"
1250 "by ICC profiles stored in:\n- %s\n- %s"), user_profile_dir, system_profile_dir);
1251 gtk_widget_set_tooltip_text(
d->profile,
tooltip);
1267 tooltip = g_strdup_printf(_(
"• perceptual: "
1268 "smoothly moves out-of-gamut colors into gamut,"
1269 "preserving gradations, but distorts in-gamut colors in the process."
1270 " note that perceptual is often a proprietary LUT that depends"
1271 " on the destination space."
1274 "• relative colorimetric: "
1275 "keeps luminance while reducing as little as possible saturation"
1276 " until colors fit in gamut."
1280 "designed to present eye-catching business graphics"
1281 " by preserving the saturation. (not suited for photography)."
1284 "• absolute colorimetric: "
1285 "adapt white point of the image to the white point of the"
1286 " destination medium and do nothing else. mainly used when"
1287 " proofing colors. (not suited for photography)."
1290 gtk_widget_set_tooltip_text(
d->intent,
tooltip);
1299 gtk_widget_set_tooltip_text(
d->style, _(
"temporary style to use while exporting"));
1302 g_signal_connect(G_OBJECT(
d->export_masks),
"value-changed", G_CALLBACK(
_callback_bool),
1304 g_signal_connect(G_OBJECT(
d->intent),
"value-changed", G_CALLBACK(
_intent_changed), (gpointer)
d);
1305 g_signal_connect(G_OBJECT(
d->profile),
"value-changed", G_CALLBACK(
_profile_changed), (gpointer)
d);
1306 g_signal_connect(G_OBJECT(
d->style),
"value-changed", G_CALLBACK(
_style_changed), (gpointer)
d);
1312 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(hbox),
FALSE,
TRUE, 0);
1317 gtk_box_pack_start(hbox, GTK_WIDGET(
d->export_button),
TRUE,
TRUE, 0);
1319 g_signal_connect(G_OBJECT(
d->width),
"changed", G_CALLBACK(
_width_changed), (gpointer)
d);
1320 g_signal_connect(G_OBJECT(
d->height),
"changed", G_CALLBACK(
_height_changed), (gpointer)
d);
1323 g_signal_connect(G_OBJECT(
d->print_dpi),
"changed", G_CALLBACK(
_print_dpi_changed), (gpointer)
d);
1325 g_signal_connect(G_OBJECT(
d->width),
"changed", G_CALLBACK(
_width_changed), (gpointer)
d);
1326 g_signal_connect(G_OBJECT(
d->height),
"changed", G_CALLBACK(
_height_changed), (gpointer)
d);
1328 g_signal_connect(G_OBJECT(
d->width),
"button-press-event", G_CALLBACK(
_widht_mdlclick), (gpointer)
d);
1329 g_signal_connect(G_OBJECT(
d->height),
"button-press-event", G_CALLBACK(
_height_mdlclick), (gpointer)
d);
1330 g_signal_connect(G_OBJECT(
d->print_width),
"button-press-event", G_CALLBACK(
_widht_mdlclick), (gpointer)
d);
1331 g_signal_connect(G_OBJECT(
d->print_height),
"button-press-event", G_CALLBACK(
_height_mdlclick), (gpointer)
d);
1333 g_signal_connect(G_OBJECT(
d->scale),
"button-press-event", G_CALLBACK(
_scale_mdlclick), (gpointer)
d);
1334 g_signal_connect(G_OBJECT(
d->scale),
"changed", G_CALLBACK(
_scale_changed), (gpointer)
d);
1337 gtk_widget_show_all(self->
widget);
1338 gtk_widget_set_no_show_all(self->
widget,
TRUE);
1341 gtk_entry_set_text(GTK_ENTRY(
d->width), setting);
1343 gtk_entry_set_text(GTK_ENTRY(
d->height), setting);
1377 gboolean rc =
FALSE;
1412 if(module->widget && GTK_IS_CONTAINER(
d->storage_extra_container)) gtk_container_remove(GTK_CONTAINER(
d->storage_extra_container),
module->widget);
1418 if(module->widget && GTK_IS_CONTAINER(
d->format_extra_container)) gtk_container_remove(GTK_CONTAINER(
d->format_extra_container),
module->widget);
1442 const int version = self->version();
1447 for(GList *l = presets; l; l = g_list_next(l))
1450 const int rowid =
p->rowid;
1451 const int op_version =
p->op_version;
1452 const void *op_params =
p->op_params;
1453 const size_t op_params_size =
p->op_params_size;
1454 const char *
name =
p->name;
1456 if(op_version != version)
1459 fprintf(stderr,
"[export_init_presets] found export preset '%s' with version %d, version %d was "
1460 "expected. dropping preset.\n",
1461 name, op_version, version);
1467 const char *buf = (
const char *)op_params;
1470 buf += 6 *
sizeof(int32_t);
1472 buf += strlen(buf) + 1;
1474 buf += strlen(buf) + 1;
1477 const char *fname = buf;
1478 buf += strlen(fname) + 1;
1479 const char *sname = buf;
1480 buf += strlen(sname) + 1;
1485 if(!fmod || !smod)
continue;
1488 size_t copy_over_part = (
void *)buf - (
void *)op_params;
1490 const int fversion = *(
const int *)buf;
1491 buf +=
sizeof(int32_t);
1492 const int sversion = *(
const int *)buf;
1493 buf +=
sizeof(int32_t);
1494 const int fsize = *(
const int *)buf;
1495 buf +=
sizeof(int32_t);
1496 const int ssize = *(
const int *)buf;
1497 buf +=
sizeof(int32_t);
1499 const void *fdata = buf;
1501 const void *sdata = buf;
1503 void *new_fdata = NULL, *new_sdata = NULL;
1504 size_t new_fsize = fsize, new_ssize = ssize;
1505 const int32_t new_fversion = fmod->version(), new_sversion = smod->version();
1507 if(fversion < new_fversion)
1509 if(!(fmod->legacy_params
1510 && (new_fdata = fmod->legacy_params(fmod, fdata, fsize, fversion, new_fversion, &new_fsize))
1515 if(sversion < new_sversion)
1517 if(!(smod->legacy_params
1518 && (new_sdata = smod->legacy_params(smod, sdata, ssize, sversion, new_sversion, &new_ssize))
1523 if(new_fdata || new_sdata)
1526 const size_t new_params_size = op_params_size - (fsize + ssize) + (new_fsize + new_ssize);
1527 void *new_params = malloc(new_params_size);
1528 memcpy(new_params, op_params, copy_over_part);
1530 size_t pos = copy_over_part;
1531 memcpy((uint8_t *)new_params + pos, &new_fversion,
sizeof(int32_t));
1532 pos +=
sizeof(int32_t);
1533 memcpy((uint8_t *)new_params + pos, &new_sversion,
sizeof(int32_t));
1534 pos +=
sizeof(int32_t);
1535 memcpy((uint8_t *)new_params + pos, &new_fsize,
sizeof(int32_t));
1536 pos +=
sizeof(int32_t);
1537 memcpy((uint8_t *)new_params + pos, &new_ssize,
sizeof(int32_t));
1538 pos +=
sizeof(int32_t);
1540 memcpy((uint8_t *)new_params + pos, new_fdata, new_fsize);
1542 memcpy((uint8_t *)new_params + pos, fdata, fsize);
1545 memcpy((uint8_t *)new_params + pos, new_sdata, new_ssize);
1547 memcpy((uint8_t *)new_params + pos, sdata, ssize);
1551 "[export_init_presets] updating export preset '%s' from versions %d/%d to versions %d/%d\n",
1552 name, fversion, sversion, new_fversion, new_sversion);
1567 fprintf(stderr,
"[export_init_presets] export preset '%s' can't be updated from versions %d/%d to "
1568 "versions %d/%d. dropping preset\n",
1569 name, fversion, sversion, new_fversion, new_sversion);
1577 const int old_version,
int *new_version,
size_t *new_size)
1579 if(old_version == 1)
1582 const size_t new_params_size = old_params_size + 2 *
sizeof(int32_t);
1583 void *new_params = malloc(new_params_size);
1585 const char *buf = (
const char *)old_params;
1588 buf += 3 *
sizeof(int32_t);
1590 buf += strlen(buf) + 1;
1593 const char *fname = buf;
1594 buf += strlen(fname) + 1;
1595 const char *sname = buf;
1596 buf += strlen(sname) + 1;
1610 size_t first_half = (
void *)buf - (
void *)old_params;
1611 memcpy(new_params, old_params, first_half);
1614 int32_t fversion = 1;
1615 int32_t sversion = (strcmp(sname,
"picasa") == 0 ? 2 : 1);
1616 memcpy((uint8_t *)new_params + first_half, &fversion,
sizeof(int32_t));
1617 memcpy((uint8_t *)new_params + first_half +
sizeof(int32_t), &sversion,
sizeof(int32_t));
1619 memcpy((uint8_t *)new_params + first_half +
sizeof(int32_t) * 2, buf, old_params_size - first_half);
1621 *new_size = new_params_size;
1625 else if(old_version == 2)
1628 const size_t new_params_size = old_params_size +
sizeof(int32_t);
1629 void *new_params = calloc(1, new_params_size);
1631 memcpy(new_params, old_params,
sizeof(int32_t) * 2);
1632 memcpy((uint8_t *)new_params +
sizeof(int32_t) * 3, (uint8_t *)old_params +
sizeof(int32_t) * 2, old_params_size -
sizeof(int32_t) * 2);
1634 *new_size = new_params_size;
1638 else if(old_version == 3)
1650 const char *buf = (
const char *)old_params;
1653 const char *iccprofile = buf + 4 *
sizeof(int32_t);
1655 size_t new_params_size = old_params_size - strlen(iccprofile) +
sizeof(int32_t);
1657 const char *iccfilename =
"";
1659 if(!strcmp(iccprofile,
"image"))
1661 else if(!strcmp(iccprofile,
"sRGB"))
1663 else if(!strcmp(iccprofile,
"linear_rec709_rgb") || !strcmp(iccprofile,
"linear_rgb"))
1665 else if(!strcmp(iccprofile,
"linear_rec2020_rgb"))
1667 else if(!strcmp(iccprofile,
"adobergb"))
1672 iccfilename = iccprofile;
1673 new_params_size += strlen(iccfilename);
1676 void *new_params = calloc(1, new_params_size);
1678 memcpy(new_params, old_params,
sizeof(int32_t) * 4);
1679 pos += 4 *
sizeof(int32_t);
1680 memcpy((uint8_t *)new_params + pos, &icctype,
sizeof(int32_t));
1681 pos +=
sizeof(int32_t);
1682 memcpy((uint8_t *)new_params + pos, iccfilename, strlen(iccfilename) + 1);
1683 pos += strlen(iccfilename) + 1;
1684 size_t old_pos = 4 *
sizeof(int32_t) + strlen(iccprofile) + 1;
1685 memcpy((uint8_t *)new_params + pos, (uint8_t *)old_params + old_pos, old_params_size - old_pos);
1687 *new_size = new_params_size;
1691 else if(old_version == 4)
1704 const size_t new_params_size = old_params_size +
sizeof(int32_t);
1705 void *new_params = calloc(1, new_params_size);
1708 memcpy(new_params, old_params,
sizeof(int32_t) * 3);
1709 pos += 4 *
sizeof(int32_t);
1710 memcpy((uint8_t *)new_params + pos, (uint8_t *)old_params + pos -
sizeof(int32_t), old_params_size -
sizeof(int32_t) * 3);
1712 *new_size = new_params_size;
1716 else if(old_version == 5)
1732 const int flags_size = strlen(
flags) + 1;
1733 const size_t new_params_size = old_params_size + flags_size;
1734 void *new_params = calloc(1, new_params_size);
1736 memcpy(new_params, old_params,
sizeof(int32_t) * 6);
1737 pos += 6 *
sizeof(int32_t);
1738 memcpy((uint8_t *)new_params + pos,
flags, flags_size);
1740 memcpy((uint8_t *)new_params + pos, (uint8_t *)old_params + pos - flags_size, old_params_size -
sizeof(int32_t) * 6);
1743 *new_size = new_params_size;
1747 else if(old_version == 6)
1758 const size_t new_params_size = old_params_size +
sizeof(int32_t);
1759 void *new_params = calloc(1, new_params_size);
1762 memcpy(new_params, old_params,
sizeof(int32_t) * 4);
1763 pos += 5 *
sizeof(int32_t);
1764 memcpy((uint8_t *)new_params + pos, (uint8_t *)old_params + pos -
sizeof(int32_t), old_params_size -
sizeof(int32_t) * 4);
1766 *new_size = new_params_size;
1783 size_t fsize = mformat->params_size(mformat);
1785 size_t ssize = mstorage->params_size(mstorage);
1786 void *sdata = mstorage->get_params(mstorage);
1787 const int32_t fversion = mformat->version();
1788 const int32_t sversion = mstorage->version();
1809 const int32_t upscale =
FALSE;
1810 const int32_t high_quality =
TRUE;
1814 const char *metadata_export =
d->metadata_export;
1818 g_strlcpy(fdata->
style, style,
sizeof(fdata->
style));
1826 if(!iccfilename) iccfilename = g_strdup(
"");
1827 if(
IS_NULL_PTR(metadata_export)) metadata_export = g_strdup(
"");
1831 const int32_t fname_len = strlen(fname);
1832 const int32_t sname_len = strlen(sname);
1834 *
size = fname_len + sname_len + 2 + 4 *
sizeof(int32_t) + fsize + ssize + 7 *
sizeof(int32_t)
1835 + strlen(iccfilename) + 1 + strlen(metadata_export) + 1;
1837 char *params = (
char *)calloc(1, *
size);
1839 memcpy(params + pos, &max_width,
sizeof(int32_t));
1840 pos +=
sizeof(int32_t);
1841 memcpy(params + pos, &max_height,
sizeof(int32_t));
1842 pos +=
sizeof(int32_t);
1843 memcpy(params + pos, &upscale,
sizeof(int32_t));
1844 pos +=
sizeof(int32_t);
1845 memcpy(params + pos, &high_quality,
sizeof(int32_t));
1846 pos +=
sizeof(int32_t);
1847 memcpy(params + pos, &export_masks,
sizeof(int32_t));
1848 pos +=
sizeof(int32_t);
1849 memcpy(params + pos, &iccintent,
sizeof(int32_t));
1850 pos +=
sizeof(int32_t);
1851 memcpy(params + pos, &icctype,
sizeof(int32_t));
1852 pos +=
sizeof(int32_t);
1853 memcpy(params + pos, metadata_export, strlen(metadata_export) + 1);
1854 pos += strlen(metadata_export) + 1;
1855 memcpy(params + pos, iccfilename, strlen(iccfilename) + 1);
1856 pos += strlen(iccfilename) + 1;
1857 memcpy(params + pos, fname, fname_len + 1);
1858 pos += fname_len + 1;
1859 memcpy(params + pos, sname, sname_len + 1);
1860 pos += sname_len + 1;
1861 memcpy(params + pos, &fversion,
sizeof(int32_t));
1862 pos +=
sizeof(int32_t);
1863 memcpy(params + pos, &sversion,
sizeof(int32_t));
1864 pos +=
sizeof(int32_t);
1865 memcpy(params + pos, &fsize,
sizeof(int32_t));
1866 pos +=
sizeof(int32_t);
1867 memcpy(params + pos, &ssize,
sizeof(int32_t));
1868 pos +=
sizeof(int32_t);
1871 memcpy(params + pos, fdata, fsize);
1876 memcpy(params + pos, sdata, ssize);
1879 g_assert(pos == *
size);
1884 if(fdata) mformat->free_params(mformat, fdata);
1885 if(sdata) mstorage->free_params(mstorage, sdata);
1893 const char *buf = (
const char *)params;
1895 const int max_width = *(
const int *)buf;
1896 buf +=
sizeof(int32_t);
1897 const int max_height = *(
const int *)buf;
1898 buf +=
sizeof(int32_t);
1900 buf +=
sizeof(int32_t);
1902 buf +=
sizeof(int32_t);
1903 const int export_masks = *(
const int *)buf;
1904 buf +=
sizeof(int32_t);
1905 const int iccintent = *(
const int *)buf;
1906 buf +=
sizeof(int32_t);
1907 const int icctype = *(
const int *)buf;
1908 buf +=
sizeof(int32_t);
1909 const char *metadata_export = buf;
1910 buf += strlen(metadata_export) + 1;
1912 d->metadata_export = g_strdup(metadata_export);
1914 const char *iccfilename = buf;
1915 buf += strlen(iccfilename) + 1;
1929 const char *fname = buf;
1930 buf += strlen(fname) + 1;
1931 const char *sname = buf;
1932 buf += strlen(sname) + 1;
1937 if(!fmod || !smod)
return 1;
1939 const int32_t fversion = *(
const int32_t *)buf;
1940 buf +=
sizeof(int32_t);
1941 const int32_t sversion = *(
const int32_t *)buf;
1942 buf +=
sizeof(int32_t);
1944 const int fsize = *(
const int *)buf;
1945 buf +=
sizeof(int32_t);
1946 const int ssize = *(
const int *)buf;
1947 buf +=
sizeof(int32_t);
1950 != strlen(fname) + strlen(sname) + 2 + 4 *
sizeof(int32_t) + fsize + ssize + 7 *
sizeof(int32_t)
1951 + strlen(iccfilename) + 1 + strlen(metadata_export) + 1)
1953 if(fversion != fmod->version() || sversion != smod->version())
return 1;
1957 if(fdata->
style[0] ==
'\0')
1963 const void *sdata = buf;
1975 if(ssize)
res += smod->set_params(smod, sdata, ssize);
1976 if(fsize)
res += fmod->set_params(fmod, fdata, fsize);
void dt_accels_disconnect_on_text_input(GtkWidget *widget)
Disconnect accels while a text or search entry has the focus, and reconnect them when it loses it....
Handle default and user-set shortcuts (accelerators)
int dt_act_on_get_images_nb(const gboolean only_visible, const gboolean force)
GList * dt_act_on_get_images()
GtkWidget * dt_gui_main_window(void)
void dt_bauhaus_combobox_clear(GtkWidget *widget)
int dt_bauhaus_combobox_get(GtkWidget *widget)
const char * dt_bauhaus_combobox_get_text(GtkWidget *widget)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
gboolean dt_bauhaus_combobox_set_from_text(GtkWidget *widget, const char *text)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
#define DT_BAUHAUS_COMBOBOX_NEW_FULL(bauhaus, widget, action, label, tip, pos, callback, data,...)
dt_collection_properties_t
size_t dt_colorspaces_enumerate_profiles(const dt_colorspaces_profile_role_t role, dt_colorprofile_desc_t **out)
Ordered snapshot of every profile registered for one role.
int dt_colorspaces_profile_index(const dt_colorspaces_profile_role_t role, const dt_colorspaces_color_profile_type_t type, const char *const filename)
Combo position of (type, filename) within direction.
gboolean dt_colorspaces_profile_at(const dt_colorspaces_profile_role_t role, const int index, dt_colorprofile_desc_t *const out)
Identity of the profile at index within direction.
The colour-profile module's API: which profiles exist, and how to apply one.
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
void dt_conf_set_bool(const char *name, int val)
int dt_conf_get_bool(const char *name)
gchar * dt_conf_get_string(const char *name)
Read the stored string for name as a private copy.
void dt_conf_set_int(const char *name, int val)
gboolean dt_confgen_get_bool(const char *name, dt_confgen_value_kind_t kind)
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
int dt_confgen_get_int(const char *name, dt_confgen_value_kind_t kind)
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
Borrow the stored string for name without copying it.
const char * dt_confgen_get(const char *name, dt_confgen_value_kind_t kind)
One declared attribute of name from the generated XML, as text.
void dt_gui_container_remove_children(GtkContainer *container)
void dt_gui_flow_box_as_layout(GtkFlowBox *box)
void dt_control_log(const char *msg,...)
void dt_control_export(GList *imgid_list, int max_width, int max_height, int format_index, int storage_index, gboolean high_quality, gboolean export_masks, char *style, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent, const gchar *metadata_export)
struct dt_imageio_t * dt_imageio_get_global(void)
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
static float pixels2cm(dt_lib_export_t *self, const uint32_t pix)
static void _format_changed(GtkWidget *widget, dt_lib_export_t *d)
void gui_reset(dt_lib_module_t *self)
static void _callback_bool(GtkWidget *widget, gpointer user_data)
void _menuitem_preferences(GtkMenuItem *menuitem, dt_lib_module_t *self)
int set_params(dt_lib_module_t *self, const void *params, int size)
static void _update(dt_lib_module_t *self)
static void _height_changed(GtkEditable *entry, gpointer user_data)
char * dt_lib_export_metadata_configuration_dialog(char *list, const gboolean ondisk)
static float pixels2inch(dt_lib_export_t *self, const uint32_t pix)
static void _print_height_changed(GtkEditable *entry, gpointer user_data)
void * get_params(dt_lib_module_t *self, int *size)
static float pixels2print(dt_lib_export_t *self, const uint32_t pix)
void set_preferences(void *menu, dt_lib_module_t *self)
static void _intent_changed(GtkWidget *widget, dt_lib_export_t *d)
static uint32_t inch2pixels(dt_lib_export_t *self, const float inch)
static void _scale_changed(GtkEntry *spin, dt_lib_export_t *d)
static void _profile_changed(GtkWidget *widget, dt_lib_export_t *d)
static void _scale_optim()
static void _print_width_changed(GtkEditable *entry, gpointer user_data)
static gboolean _scale_mdlclick(GtkEntry *spin, GdkEventButton *event, dt_lib_export_t *d)
void gui_cleanup(dt_lib_module_t *self)
static uint32_t print2pixels(dt_lib_export_t *self, const float value)
static void _print_dpi_changed(GtkWidget *widget, gpointer user_data)
static void _on_storage_list_changed(gpointer instance, dt_lib_module_t *self)
static void _dimensions_type_changed(GtkWidget *widget, dt_lib_export_t *d)
static void _style_changed(GtkWidget *widget, dt_lib_export_t *d)
static void set_format_by_name(dt_lib_export_t *d, const char *name)
static void _validate_dimensions(dt_lib_export_t *d)
void _size_update_display(dt_lib_export_t *self)
#define EXPORT_MAX_IMAGE_SIZE
static void _update_formats_combobox(dt_lib_export_t *d)
void init_presets(dt_lib_module_t *self)
static void _update_dimensions(dt_lib_export_t *d)
static void _resync_print_dimensions(dt_lib_export_t *self)
static void _collection_updated_callback(gpointer instance, dt_collection_change_t query_change, dt_collection_properties_t changed_property, gpointer imgs, int next, dt_lib_module_t *self)
static void _widht_mdlclick(GtkEntry *spin, GdkEventButton *event, gpointer user_data)
uint32_t container(dt_lib_module_t *self)
static void _height_mdlclick(GtkEntry *spin, GdkEventButton *event, gpointer user_data)
static void _size_in_px_update(dt_lib_export_t *d)
static void _storage_changed(GtkWidget *widget, dt_lib_export_t *d)
void _set_dimensions(dt_lib_export_t *d, uint32_t max_width, uint32_t max_height)
static void _export_button_clicked(GtkWidget *widget, dt_lib_export_t *d)
void gui_init(dt_lib_module_t *self)
gboolean _is_int(double value)
const char ** views(dt_lib_module_t *self)
static void _image_selection_changed_callback(gpointer instance, dt_lib_module_t *self)
void * legacy_params(dt_lib_module_t *self, const void *const old_params, const size_t old_params_size, const int old_version, int *new_version, size_t *new_size)
static uint32_t cm2pixels(dt_lib_export_t *self, const float cm)
static void set_storage_by_name(dt_lib_export_t *d, const char *name)
static void _width_changed(GtkEditable *entry, gpointer user_data)
static void _get_max_output_dimension(dt_lib_export_t *d, uint32_t *width, uint32_t *height)
static void _resync_pixel_dimensions(dt_lib_export_t *self)
static void _lib_export_styles_changed_callback(gpointer instance, gpointer user_data)
void dt_loc_get_datadir(char *datadir, size_t bufsize)
void dt_loc_get_user_config_dir(char *configdir, size_t bufsize)
dt_imageio_module_storage_t * dt_imageio_get_storage()
int dt_imageio_get_index_of_format(dt_imageio_module_format_t *format)
int dt_imageio_get_index_of_storage(dt_imageio_module_storage_t *storage)
gchar * dt_imageio_resizing_factor_get_and_parsing(double *num, double *denum)
dt_imageio_module_format_t * dt_imageio_get_format()
dt_imageio_module_format_t * dt_imageio_get_format_by_name(const char *name)
dt_imageio_module_storage_t * dt_imageio_get_storage_by_name(const char *name)
GtkWidget * dt_ui_section_label_new(const gchar *str)
void dt_lib_cancel_postponed_update(dt_lib_module_t *mod)
GtkWidget * dt_action_button_new(dt_lib_module_t *self, const gchar *label, gpointer callback, gpointer data, const gchar *tooltip, guint accel_key, GdkModifierType mods)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
dt_mipmap_buffer_dsc_flags flags
#define DT_MODULE(MODVER)
Instantiate the version handshake every module must export. Use once, at file scope,...
void dt_osx_disallow_fullscreen(GtkWidget *widget)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
void dt_module_preset_free(gpointer data)
Release one dt_module_preset_t. Suits g_list_free_full().
GList * dt_preset_repository_list_all_versions(const char *operation)
Every preset of operation at ANY version, with rowid and op_version filled in, SHIPPED FIRST then by ...
void dt_preset_repository_update_params_by_rowid(const int rowid, const int op_version, const void *params, const int params_size)
Replace the parameters of one row, by rowid.
void dt_preset_repository_delete_by_rowid(const int rowid)
Delete one row by rowid.
data.presets: a module's saved parameters, with the conditions under which it auto-applies.
static dt_colorspaces_color_profile_type_t sanitize_colorspaces(dt_colorspaces_color_profile_type_t colorspace)
Coerce an integer read back from storage into a colour space this build still has.
dt_iop_color_intent_t
ICC rendering intent, as stored in iop params and in conf.
dt_colorspaces_color_profile_type_t
@ DT_COLORSPACE_FILE
A user ICC file on disk; the only type whose filename is meaningful.
@ DT_COLORSPACE_SRGB
sRGB – registered TWICE, and the two entries are not interchangeable.
@ DT_COLORSPACE_NONE
No profile / "take it from the image settings". Never matches a list entry.
@ DT_COLORSPACE_LIN_REC2020
@ DT_COLORSPACE_LIN_REC709
@ DT_PROFILE_ROLE_OUTPUT
Listed in the output/export-profile combo (colorout, export).
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_STYLE_CHANGED
This signal is raised when a style is added/deleted/changed
@ DT_SIGNAL_IMAGEIO_STORAGE_CHANGE
This signal is raised when a new storage module is loaded noparameters no return.
@ DT_SIGNAL_SELECTION_CHANGED
This signal is raised when the selection is changed no param, no returned value.
@ DT_SIGNAL_COLLECTION_CHANGED
This signal is raised when collection changed. To avoid leaking the list, dt_collection_t is connecte...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
static const dt_aligned_pixel_simd_t value
void dt_style_free(gpointer data)
GList * dt_styles_get_list(const char *filter)
A profile's public identity: what the GUI displays and stores, and nothing else.
dt_colorspaces_color_profile_type_t type
what to store in params / conf
char name[512]
translated, display-ready
char filename[DT_IOP_COLOR_ICC_LEN]
"" unless type == DT_COLORSPACE_FILE
GtkButton * export_button
GtkWidget * storage_extra_container
uint32_t max_allowed_width
GtkWidget * dimensions_type
GtkWidget * format_extra_container
uint32_t max_allowed_height