22
22
#include "config.h"
24
24
#include <glib/gi18n.h>
25
26
#include <locale.h>
27
28
#include <stdlib.h>
30
#include "cd-client-sync.h"
29
31
#include "cd-common.h"
30
33
#include "cd-lcms-helpers.h"
32
static gint lcms_error_code = 0;
34
#include "cd-profile-sync.h"
37
GOptionContext *context;
42
typedef gboolean (*CdUtilPrivateCb) (CdUtilPrivate *util,
49
CdUtilPrivateCb callback;
56
cd_util_item_free (CdUtilItem *item)
59
g_free (item->description);
35
* cd_fix_profile_filename:
64
* cd_sort_command_name_cb:
67
cd_sort_command_name_cb (CdUtilItem **item1, CdUtilItem **item2)
69
return g_strcmp0 ((*item1)->name, (*item2)->name);
76
cd_util_add (GPtrArray *array, const gchar *name, const gchar *description, CdUtilPrivateCb callback)
83
names = g_strsplit (name, ",", -1);
84
for (i=0; names[i] != NULL; i++) {
85
item = g_new0 (CdUtilItem, 1);
86
item->name = g_strdup (names[i]);
88
item->description = g_strdup (description);
90
/* TRANSLATORS: this is a command alias */
91
item->description = g_strdup_printf (_("Alias to %s"),
94
item->callback = callback;
95
g_ptr_array_add (array, item);
101
* cd_util_get_descriptions:
104
cd_util_get_descriptions (GPtrArray *array)
113
/* get maximum command length */
114
for (i=0; i<array->len; i++) {
115
item = g_ptr_array_index (array, i);
116
len = strlen (item->name);
121
/* ensure we're spaced by at least this */
125
/* print each command */
126
string = g_string_new ("");
127
for (i=0; i<array->len; i++) {
128
item = g_ptr_array_index (array, i);
129
g_string_append (string, " ");
130
g_string_append (string, item->name);
131
len = strlen (item->name);
132
for (j=len; j<max_len+3; j++)
133
g_string_append_c (string, ' ');
134
g_string_append (string, item->description);
135
g_string_append_c (string, '\n');
138
/* remove trailing newline */
140
g_string_set_size (string, string->len - 1);
142
return g_string_free (string, FALSE);
38
cd_fix_profile_filename (const gchar *filename,
39
const gchar *description,
40
const gchar *copyright,
42
const gchar *manufacturer,
43
const gchar *metadata,
44
gboolean clear_metadata)
149
cd_util_run (CdUtilPrivate *priv, const gchar *command, gchar **values, GError **error)
152
gboolean ret = FALSE;
157
for (i=0; i<priv->cmd_array->len; i++) {
158
item = g_ptr_array_index (priv->cmd_array, i);
159
if (g_strcmp0 (item->name, command) == 0) {
160
ret = item->callback (priv, values, error);
166
string = g_string_new ("");
167
/* TRANSLATORS: error message */
168
g_string_append_printf (string, "%s\n",
169
_("Command not found, valid commands are:"));
170
for (i=0; i<priv->cmd_array->len; i++) {
171
item = g_ptr_array_index (priv->cmd_array, i);
172
g_string_append_printf (string, " * %s\n", item->name);
174
g_set_error_literal (error, 1, 0, string->str);
175
g_string_free (string, TRUE);
181
* cd_util_profile_read:
184
cd_util_profile_read (const gchar *filename, GError **error)
47
186
cmsHPROFILE lcms_profile = NULL;
48
188
gchar *data = NULL;
52
ret = g_file_get_contents (filename, &data, &len, &error);
54
g_warning ("failed to open profile: %s",
191
ret = g_file_get_contents (filename, &data, &len, error);
60
195
lcms_profile = cmsOpenProfileFromMem (data, len);
61
if (lcms_profile == NULL || lcms_error_code != 0) {
62
g_warning ("failed to open profile");
196
if (lcms_profile == NULL) {
197
g_set_error (error, 1, 0,
198
"failed to open profile %s",
67
/* profile version to write */
68
cmsSetProfileVersion (lcms_profile, 3.4);
69
if (description != NULL) {
70
ret = _cmsWriteTagTextAscii (lcms_profile,
71
cmsSigProfileDescriptionTag,
73
if (!ret || lcms_error_code != 0) {
74
g_warning ("failed to write description");
78
if (copyright != NULL) {
79
ret = _cmsWriteTagTextAscii (lcms_profile,
82
if (!ret || lcms_error_code != 0) {
83
g_warning ("failed to write copyright");
88
ret = _cmsWriteTagTextAscii (lcms_profile,
89
cmsSigDeviceModelDescTag,
91
if (!ret || lcms_error_code != 0) {
92
g_warning ("failed to write model");
96
if (manufacturer != NULL) {
97
ret = _cmsWriteTagTextAscii (lcms_profile,
98
cmsSigDeviceMfgDescTag,
100
if (!ret || lcms_error_code != 0) {
101
g_warning ("failed to write manufacturer");
105
if (metadata != NULL) {
106
ret = cd_profile_write_metadata_string (lcms_profile,
112
g_warning ("failed to write metadata: %s",
114
g_error_free (error);
208
* cd_util_profile_write:
211
cd_util_profile_write (cmsHPROFILE lcms_profile, const gchar *filename, GError **error)
119
215
/* write profile id */
120
216
ret = cmsMD5computeID (lcms_profile);
121
if (!ret || lcms_error_code != 0) {
122
g_warning ("failed to write profile id");
126
cmsSaveProfileToFile (lcms_profile, filename);
128
if (lcms_profile != NULL)
129
cmsCloseProfile (lcms_profile);
218
g_set_error (error, 1, 0,
219
"failed to compute profile id for %s",
225
ret = cmsSaveProfileToFile (lcms_profile, filename);
227
g_set_error (error, 1, 0,
228
"failed to save profile to %s",
237
* cd_util_profile_set_text_acsii:
240
cd_util_profile_set_text_acsii (cmsHPROFILE lcms_profile,
247
ret = _cmsWriteTagTextAscii (lcms_profile, sig, value);
249
g_set_error (error, 1, 0,
250
"failed to write '%s'",
259
* cd_util_set_info_text:
262
cd_util_set_info_text (CdUtilPrivate *priv, cmsTagSignature sig, gchar **values, GError **error)
264
cmsHPROFILE lcms_profile = NULL;
267
/* check arguments */
268
if (g_strv_length (values) != 2) {
270
g_set_error_literal (error, 1, 0,
271
"invalid input, expect 'value' 'filename'");
276
lcms_profile = cd_util_profile_read (values[1], error);
277
if (lcms_profile == NULL) {
283
ret = cd_util_profile_set_text_acsii (lcms_profile,
291
ret = cd_util_profile_write (lcms_profile, values[1], error);
295
if (lcms_profile != NULL)
296
cmsCloseProfile (lcms_profile);
301
* cd_util_set_copyright:
304
cd_util_set_copyright (CdUtilPrivate *priv, gchar **values, GError **error)
306
return cd_util_set_info_text (priv, cmsInfoCopyright, values, error);
310
* cd_util_set_description:
313
cd_util_set_description (CdUtilPrivate *priv, gchar **values, GError **error)
315
return cd_util_set_info_text (priv, cmsInfoDescription, values, error);
319
* cd_util_set_manufacturer:
322
cd_util_set_manufacturer (CdUtilPrivate *priv, gchar **values, GError **error)
324
return cd_util_set_info_text (priv, cmsInfoManufacturer, values, error);
331
cd_util_set_model (CdUtilPrivate *priv, gchar **values, GError **error)
333
return cd_util_set_info_text (priv, cmsInfoModel, values, error);
337
* cd_util_clear_metadata:
340
cd_util_clear_metadata (CdUtilPrivate *priv, gchar **values, GError **error)
342
cmsHANDLE dict = NULL;
343
cmsHPROFILE lcms_profile = NULL;
346
/* check arguments */
347
if (g_strv_length (values) != 1) {
349
g_set_error_literal (error, 1, 0,
350
"invalid input, expect 'filename'");
355
lcms_profile = cd_util_profile_read (values[0], error);
356
if (lcms_profile == NULL) {
362
ret = cmsWriteTag (lcms_profile, cmsSigMetaTag, dict);
364
g_set_error_literal (error, 1, 0,
365
"cannot write empty dict tag");
370
ret = cd_util_profile_write (lcms_profile, values[0], error);
374
if (lcms_profile != NULL)
375
cmsCloseProfile (lcms_profile);
380
* cd_util_get_standard_space_filename:
383
cd_util_get_standard_space_filename (CdUtilPrivate *priv,
384
CdStandardSpace standard_space,
387
CdProfile *profile_tmp;
389
gchar *filename = NULL;
392
profile_tmp = cd_client_get_standard_space_sync (priv->client,
396
if (profile_tmp == NULL)
400
ret = cd_profile_connect_sync (profile_tmp, NULL, error);
403
filename = g_strdup (cd_profile_get_filename (profile_tmp));
405
if (profile_tmp != NULL)
406
g_object_unref (profile_tmp);
412
cmsFloat32Number *data;
413
} CdUtilGamutCdeckHelper;
416
* cd_util_get_coverage_sample_cb:
418
static cmsInt32Number
419
cd_util_get_coverage_sample_cb (const cmsFloat32Number in[],
420
cmsFloat32Number out[],
423
CdUtilGamutCdeckHelper *helper = (CdUtilGamutCdeckHelper *) user_data;
424
helper->data[helper->idx++] = in[0];
425
helper->data[helper->idx++] = in[1];
426
helper->data[helper->idx++] = in[2];
431
* cd_util_get_coverage:
432
* @profile: A valid #CdUtil
433
* @filename_in: A filename to proof against
434
* @error: A #GError, or %NULL
436
* Gets the gamut coverage of two profiles
438
* Return value: A positive value for success, or -1.0 for error.
441
cd_util_get_coverage (cmsHPROFILE profile_proof,
442
const gchar *filename_in,
445
const guint cube_size = 33;
446
cmsFloat32Number *data = NULL;
447
cmsHPROFILE profile_in = NULL;
448
cmsHPROFILE profile_null = NULL;
449
cmsHTRANSFORM transform = NULL;
450
cmsUInt16Number *alarm_codes = NULL;
451
cmsUInt32Number dimensions[] = { cube_size, cube_size, cube_size };
452
CdUtilGamutCdeckHelper helper;
454
gdouble coverage = -1.0;
456
guint data_len = cube_size * cube_size * cube_size;
459
/* load profiles into lcms */
460
profile_null = cmsCreateNULLProfile ();
461
profile_in = cmsOpenProfileFromFile (filename_in, "r");
462
if (profile_in == NULL) {
463
g_set_error (error, 1, 0, "Failed to open %s", filename_in);
467
/* create a proofing transform with gamut check */
468
transform = cmsCreateProofingTransform (profile_in,
473
INTENT_ABSOLUTE_COLORIMETRIC,
474
INTENT_ABSOLUTE_COLORIMETRIC,
475
cmsFLAGS_GAMUTCHECK |
476
cmsFLAGS_SOFTPROOFING);
477
if (transform == NULL) {
478
g_set_error (error, 1, 0,
479
"Failed to setup transform for %s",
484
/* set gamut alarm to 0xffff */
485
alarm_codes = g_new0 (cmsUInt16Number, cmsMAXCHANNELS);
486
alarm_codes[0] = 0xffff;
487
cmsSetAlarmCodes (alarm_codes);
489
/* slice profile in regular intevals */
490
data = g_new0 (cmsFloat32Number, data_len * 3);
493
ret = cmsSliceSpaceFloat (3, dimensions,
494
cd_util_get_coverage_sample_cb,
497
g_set_error_literal (error, 1, 0, "Failed to slice data");
501
/* transform each one of those nodes across the proofing transform */
502
cmsDoTransform (transform, helper.data, helper.data, data_len);
504
/* count the nodes that gives you zero and divide by total number */
505
for (i = 0; i < data_len; i++) {
506
if (helper.data[i] == 0.0)
511
coverage = (gdouble) cnt / (gdouble) data_len;
512
g_assert (coverage >= 0.0);
135
* cd_fix_profile_error_cb:
138
cd_fix_profile_error_cb (cmsContext ContextID,
139
cmsUInt32Number errorcode,
515
if (transform != NULL)
516
cmsDeleteTransform (transform);
517
if (profile_null != NULL)
518
cmsCloseProfile (profile_null);
519
if (profile_in != NULL)
520
cmsCloseProfile (profile_in);
525
* cd_util_get_profile_coverage:
528
cd_util_get_profile_coverage (CdUtilPrivate *priv,
530
CdStandardSpace standard_space,
533
gchar *filename = NULL;
534
gdouble coverage = -1.0f;
536
/* get the correct standard space */
537
filename = cd_util_get_standard_space_filename (priv,
540
if (filename == NULL)
543
/* work out the coverage */
544
coverage = cd_util_get_coverage (profile, filename, error);
553
* cd_util_set_fix_metadata:
556
cd_util_set_fix_metadata (CdUtilPrivate *priv, gchar **values, GError **error)
558
cmsHANDLE dict_new = NULL;
559
cmsHANDLE dict_old = NULL;
560
cmsHPROFILE lcms_profile = NULL;
561
const cmsDICTentry *entry;
567
/* check arguments */
568
if (g_strv_length (values) != 1) {
570
g_set_error_literal (error, 1, 0,
571
"invalid input, expect 'filename'");
576
lcms_profile = cd_util_profile_read (values[0], error);
577
if (lcms_profile == NULL) {
582
/* copy everything except the CMF keys */
583
dict_old = cmsReadTag (lcms_profile, cmsSigMetaTag);
584
if (dict_old == NULL) {
586
g_set_error_literal (error, 1, 0,
587
"no metadata present");
591
/* copy, but ignore the gamut keys */
592
dict_new = cmsDictAlloc (NULL);
593
for (entry = cmsDictGetEntryList (dict_old);
595
entry = cmsDictNextEntry (entry)) {
596
wcstombs (name, entry->Name, sizeof (name));
597
if (g_str_has_prefix (name, "GAMUT_volume") == 0)
599
cmsDictAddEntry (dict_new,
606
/* get coverages of common spaces */
607
if (cmsGetColorSpace (lcms_profile) == cmsSigRgbData) {
609
/* get the gamut coverage for sRGB */
610
coverage = cd_util_get_profile_coverage (priv,
612
CD_STANDARD_SPACE_ADOBE_RGB,
614
if (coverage < 0.0) {
618
coverage_tmp = g_strdup_printf ("%f", coverage);
619
_cmsDictAddEntryAscii (dict_new,
620
"GAMUT_coverage(adobe-rgb)",
622
g_free (coverage_tmp);
623
g_debug ("coverage of AdobeRGB: %f%%", coverage * 100.0f);
625
/* get the gamut coverage for AdobeRGB */
626
coverage = cd_util_get_profile_coverage (priv,
628
CD_STANDARD_SPACE_SRGB,
630
if (coverage < 0.0) {
634
coverage_tmp = g_strdup_printf ("%f", coverage);
635
_cmsDictAddEntryAscii (dict_new,
636
"GAMUT_coverage(srgb)",
638
g_free (coverage_tmp);
639
g_debug ("coverage of sRGB: %f%%", coverage * 100.0f);
642
/* add CMS defines */
643
_cmsDictAddEntryAscii (dict_new,
644
CD_PROFILE_METADATA_CMF_VERSION,
646
ret = cmsWriteTag (lcms_profile, cmsSigMetaTag, dict_new);
648
g_set_error_literal (error, 1, 0,
649
"cannot initialize dict tag");
654
ret = cd_util_profile_write (lcms_profile, values[0], error);
658
if (dict_new != NULL)
659
cmsDictFree (dict_new);
660
if (lcms_profile != NULL)
661
cmsCloseProfile (lcms_profile);
666
* cd_util_init_metadata:
669
cd_util_init_metadata (CdUtilPrivate *priv, gchar **values, GError **error)
671
cmsHANDLE dict_new = NULL;
672
cmsHANDLE dict_old = NULL;
673
cmsHPROFILE lcms_profile = NULL;
674
const cmsDICTentry *entry;
678
/* check arguments */
679
if (g_strv_length (values) != 1) {
681
g_set_error_literal (error, 1, 0,
682
"invalid input, expect 'filename'");
687
lcms_profile = cd_util_profile_read (values[0], error);
688
if (lcms_profile == NULL) {
693
/* copy everything except the CMF keys */
694
dict_old = cmsReadTag (lcms_profile, cmsSigMetaTag);
695
if (dict_old == NULL) {
697
g_set_error_literal (error, 1, 0,
698
"no metadata present");
702
/* copy, but ignore the key */
703
dict_new = cmsDictAlloc (NULL);
704
for (entry = cmsDictGetEntryList (dict_old);
706
entry = cmsDictNextEntry (entry)) {
707
wcstombs (name, entry->Name, sizeof (name));
708
if (g_strcmp0 (name, CD_PROFILE_METADATA_CMF_PRODUCT) == 0)
710
if (g_strcmp0 (name, CD_PROFILE_METADATA_CMF_BINARY) == 0)
712
if (g_strcmp0 (name, CD_PROFILE_METADATA_CMF_VERSION) == 0)
714
cmsDictAddEntry (dict_new,
721
/* add CMS defines */
722
_cmsDictAddEntryAscii (dict_new,
723
CD_PROFILE_METADATA_CMF_PRODUCT,
725
_cmsDictAddEntryAscii (dict_new,
726
CD_PROFILE_METADATA_CMF_BINARY,
728
_cmsDictAddEntryAscii (dict_new,
729
CD_PROFILE_METADATA_CMF_VERSION,
731
ret = cmsWriteTag (lcms_profile, cmsSigMetaTag, dict_new);
733
g_set_error_literal (error, 1, 0,
734
"cannot initialize dict tag");
739
ret = cd_util_profile_write (lcms_profile, values[0], error);
743
if (dict_new != NULL)
744
cmsDictFree (dict_new);
745
if (lcms_profile != NULL)
746
cmsCloseProfile (lcms_profile);
751
* cd_util_remove_metadata:
754
cd_util_remove_metadata (CdUtilPrivate *priv, gchar **values, GError **error)
756
cmsHANDLE dict_new = NULL;
757
cmsHANDLE dict_old = NULL;
758
cmsHPROFILE lcms_profile = NULL;
759
const cmsDICTentry *entry;
763
/* check arguments */
764
if (g_strv_length (values) != 2) {
766
g_set_error_literal (error, 1, 0,
767
"invalid input, expect 'key' 'filename'");
772
lcms_profile = cd_util_profile_read (values[1], error);
773
if (lcms_profile == NULL) {
778
/* copy everything except the key */
779
dict_old = cmsReadTag (lcms_profile, cmsSigMetaTag);
780
if (dict_old == NULL) {
782
g_set_error_literal (error, 1, 0,
783
"no metadata present");
787
/* copy, but ignore the key */
788
dict_new = cmsDictAlloc (NULL);
789
for (entry = cmsDictGetEntryList (dict_old);
791
entry = cmsDictNextEntry (entry)) {
792
wcstombs (name, entry->Name, sizeof (name));
793
if (g_strcmp0 (name, values[0]) == 0)
795
cmsDictAddEntry (dict_new,
802
/* write the new dict */
803
ret = cmsWriteTag (lcms_profile, cmsSigMetaTag, dict_new);
805
g_set_error_literal (error, 1, 0,
806
"cannot initialize dict tag");
811
ret = cd_util_profile_write (lcms_profile, values[1], error);
815
if (dict_new != NULL)
816
cmsDictFree (dict_new);
817
if (lcms_profile != NULL)
818
cmsCloseProfile (lcms_profile);
823
* cd_util_add_metadata:
826
cd_util_add_metadata (CdUtilPrivate *priv, gchar **values, GError **error)
828
cmsHANDLE dict_new = NULL;
829
cmsHANDLE dict_old = NULL;
830
cmsHPROFILE lcms_profile = NULL;
831
const cmsDICTentry *entry;
835
/* check arguments */
836
if (g_strv_length (values) != 3) {
838
g_set_error_literal (error, 1, 0,
839
"invalid input, expect 'key' 'value' 'filename'");
844
lcms_profile = cd_util_profile_read (values[2], error);
845
if (lcms_profile == NULL) {
850
/* add CMS defines */
851
dict_old = cmsReadTag (lcms_profile, cmsSigMetaTag);
852
if (dict_old == NULL)
853
dict_old = cmsDictAlloc (NULL);
855
/* copy, but ignore the key */
856
dict_new = cmsDictAlloc (NULL);
857
for (entry = cmsDictGetEntryList (dict_old);
859
entry = cmsDictNextEntry (entry)) {
860
wcstombs (name, entry->Name, sizeof (name));
861
if (g_strcmp0 (name, values[0]) == 0)
863
cmsDictAddEntry (dict_new,
871
_cmsDictAddEntryAscii (dict_new,
874
ret = cmsWriteTag (lcms_profile, cmsSigMetaTag, dict_new);
876
g_set_error_literal (error, 1, 0,
877
"cannot write new dict tag");
882
ret = cd_util_profile_write (lcms_profile, values[2], error);
886
if (dict_new != NULL)
887
cmsDictFree (dict_new);
888
if (lcms_profile != NULL)
889
cmsCloseProfile (lcms_profile);
897
cd_util_dump (CdUtilPrivate *priv, gchar **values, GError **error)
900
cmsHPROFILE lcms_profile = NULL;
901
const cmsDICTentry* entry;
903
gchar ascii_name[1024];
904
gchar ascii_value[1024];
906
/* check arguments */
907
if (g_strv_length (values) != 1) {
909
g_set_error_literal (error, 1, 0,
910
"invalid input, expect 'filename'");
915
g_print ("Using filename %s\n", values[0]);
916
lcms_profile = cmsOpenProfileFromFile (values[0], "r");
917
if (lcms_profile == NULL) {
918
g_warning ("failed to open profile %s", values[0]);
922
ret = cmsGetProfileInfoASCII (lcms_profile, cmsInfoDescription, "en", "US", ascii_name, 1024);
924
g_print ("%s\t%s\n", _("Description"), ascii_name);
925
ret = cmsGetProfileInfoASCII (lcms_profile, cmsInfoManufacturer, "en", "US", ascii_name, 1024);
927
g_print ("%s\t%s\n", _("Manufacturer"), ascii_name);
928
ret = cmsGetProfileInfoASCII (lcms_profile, cmsInfoModel, "en", "US", ascii_name, 1024);
930
g_print ("%s\t%s\n", _("Model"), ascii_name);
931
ret = cmsGetProfileInfoASCII (lcms_profile, cmsInfoCopyright, "en", "US", ascii_name, 1024);
933
g_print ("%s\t%s\n", _("Copyright"), ascii_name);
935
/* does profile have metadata? */
936
dict = cmsReadTag (lcms_profile, cmsSigMetaTag);
938
g_print ("%s\n", _("No metadata"));
940
for (entry = cmsDictGetEntryList (dict);
942
entry = cmsDictNextEntry (entry)) {
944
/* convert from wchar_t to char */
945
wcstombs (ascii_name, entry->Name, sizeof (ascii_name));
946
wcstombs (ascii_value, entry->Value, sizeof (ascii_value));
947
g_print ("%s %s\t=\t%s\n",
948
_("Metadata"), ascii_name, ascii_value);
955
if (lcms_profile != NULL)
956
cmsCloseProfile (lcms_profile);
964
cd_util_ignore_cb (const gchar *log_domain, GLogLevelFlags log_level,
965
const gchar *message, gpointer user_data)
970
* cd_util_lcms_error_cb:
973
cd_util_lcms_error_cb (cmsContext ContextID,
974
cmsUInt32Number errorcode,
142
977
g_warning ("LCMS error %i: %s", errorcode, text);
144
/* copy this sytemwide */
145
lcms_error_code = errorcode;
152
main (int argc, char **argv)
984
main (int argc, char *argv[])
157
GOptionContext *context;
158
gchar **files = NULL;
159
gchar *description = NULL;
160
gchar *copyright = NULL;
162
gchar *manufacturer = NULL;
163
gchar *metadata = NULL;
164
gboolean clear_metadata = FALSE;
988
gboolean verbose = FALSE;
989
gchar *cmd_descriptions = NULL;
990
GError *error = NULL;
166
992
const GOptionEntry options[] = {
167
{ "description", 'd', 0, G_OPTION_ARG_STRING, &description,
168
/* TRANSLATORS: command line option */
169
_("The profile description"), NULL },
170
{ "copyright", 'c', 0, G_OPTION_ARG_STRING, ©right,
171
/* TRANSLATORS: command line option */
172
_("The profile copyright"), NULL },
173
{ "model", 'm', 0, G_OPTION_ARG_STRING, &model,
174
/* TRANSLATORS: command line option */
175
_("The device model"), NULL },
176
{ "manufacturer", 'n', 0, G_OPTION_ARG_STRING, &manufacturer,
177
/* TRANSLATORS: command line option */
178
_("The device manufacturer"), NULL },
179
{ "clear-metadata", '\0', 0, G_OPTION_ARG_NONE, &clear_metadata,
180
/* TRANSLATORS: command line option */
181
_("Clear existing metadata in the profile"), NULL },
182
{ "metadata", 'n', 0, G_OPTION_ARG_STRING, &metadata,
183
/* TRANSLATORS: command line option */
184
_("Extra metadata in 'key1=value1,key2=value2' format"), NULL },
185
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &files,
186
/* TRANSLATORS: command line option */
187
_("Profiles to fix"), NULL },
993
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
994
/* TRANSLATORS: command line option */
995
_("Show extra debugging information"), NULL },