49
53
internal_error (void)
51
55
fprintf (stderr, _("Internal error. Please "
52
"contact <libexif-devel@"
53
"lists.sourceforge.net>."));
54
58
fputc ('\n', stderr);
59
show_entry (ExifEntry *entry, const char *caption)
63
show_entry (ExifEntry *entry, unsigned int machine_readable)
65
ExifIfd ifd = exif_entry_get_ifd (entry);
67
if (machine_readable) {
70
fprintf (stdout, "%s\n", C(exif_entry_get_value (entry, b, sizeof (b))));
61
74
printf (_("EXIF entry '%s' (0x%x, '%s') exists in IFD '%s':"),
62
C(exif_tag_get_title (entry->tag)), entry->tag,
63
C(exif_tag_get_name (entry->tag)), caption);
75
C(exif_tag_get_title_in_ifd (entry->tag, ifd)), entry->tag,
76
C(exif_tag_get_name_in_ifd (entry->tag, ifd)),
77
C(exif_ifd_get_name (ifd)));
66
exif_entry_dump(entry, 0);
80
exif_entry_dump (entry, 0);
70
search_entry (ExifData *ed, ExifTag tag)
84
search_entry (ExifData *ed, ExifTag tag, unsigned int machine_readable)
122
136
} else end = value_p++;
124
138
buf = malloc ((end - begin + 1) * sizeof (char));
125
strncpy (buf, begin, end - begin);
139
strncpy ((char *) buf, (char *) begin, end - begin);
126
140
buf[end - begin] = '\0';
128
142
s = exif_format_get_size (e->format);
129
143
switch (e->format) {
130
144
case EXIF_FORMAT_ASCII:
131
internal_error (); /* Previously handled */
145
internal_error (); /* Previously handled */
133
147
case EXIF_FORMAT_SHORT:
134
exif_set_short (e->data + (s * i), o, atoi (buf));
148
exif_set_short (e->data + (s * i), o, atoi ((char *) buf));
136
150
case EXIF_FORMAT_LONG:
137
exif_set_long (e->data + (s * i), o, atol (buf));
151
exif_set_long (e->data + (s * i), o, atol ((char *) buf));
139
153
case EXIF_FORMAT_SLONG:
140
exif_set_slong (e->data + (s * i), o, atol (buf));
154
exif_set_slong (e->data + (s * i), o, atol ((char *) buf));
142
156
case EXIF_FORMAT_RATIONAL:
143
157
case EXIF_FORMAT_SRATIONAL:
147
161
fputc ('\n', stderr);
168
/* escape codes for output colors */
169
#define COL_BLUE "\033[34m"
170
#define COL_GREEN "\033[32m"
171
#define COL_RED "\033[31m"
172
#define COL_NORMAL "\033[0m"
174
/* Ensure that we're actuall printing the escape codes to a TTY.
175
* FIXME: We should make sure the terminal can actually understand these
179
#if defined(HAVE_ISATTY) && defined(HAVE_FILENO)
180
# define file_is_tty(file) (isatty(fileno(file)))
182
# define file_is_tty(file) (0==1)
185
#define put_colorstring(file, colorstring) \
187
if (file_is_tty(file)) { \
188
fputs (colorstring, file); \
193
log_func_exit (ExifLog *log, ExifLogCode code, const char *domain,
194
const char *format, va_list args, void *data)
198
put_colorstring (stderr, COL_RED);
199
vfprintf (stderr, format, args);
200
fprintf (stderr, "\n");
201
put_colorstring (stderr, COL_NORMAL);
203
case EXIF_LOG_CODE_NO_MEMORY:
204
case EXIF_LOG_CODE_CORRUPT_DATA:
205
put_colorstring (stderr, COL_RED);
206
fprintf (stderr, "%s (%s):\n", exif_log_code_get_title (code), domain);
207
vfprintf (stderr, format, args);
208
fprintf (stderr, "\n");
209
put_colorstring (stderr, COL_NORMAL);
156
save_exif_data_to_file (ExifData *ed, const char *fname, const char *target)
217
save_exif_data_to_file (ExifData *ed, ExifLog *log,
218
const char *fname, const char *target)
159
221
unsigned char *d = NULL;
162
/* Parse the JPEG file */
163
jdata = jpeg_data_new_from_file (fname);
165
fprintf (stderr, _("Could not parse JPEG file '%s'."),
167
fputc ('\n', stderr);
224
/* Parse the JPEG file. */
225
jdata = jpeg_data_new ();
226
jpeg_data_log (jdata, log);
227
jpeg_data_load_file (jdata, fname);
171
229
/* Make sure the EXIF data is not too big. */
172
230
exif_data_save_data (ed, &d, &ds);
195
#define COL_BLUE "\033[34m"
196
#define COL_GREEN "\033[32m"
197
#define COL_RED "\033[31m"
198
#define COL_NORMAL "\033[0m"
201
254
log_func (ExifLog *log, ExifLogCode code, const char *domain,
202
255
const char *format, va_list args, void *data)
259
put_colorstring (stderr, COL_RED);
260
vfprintf (stderr, format, args);
261
fprintf (stderr, "\n");
262
put_colorstring (stderr, COL_NORMAL);
205
264
case EXIF_LOG_CODE_DEBUG:
207
printf ("%s: ", domain);
208
vprintf (format, args);
265
put_colorstring (stdout, COL_GREEN);
266
fprintf (stdout, "%s: ", domain);
267
vfprintf (stdout, format, args);
268
put_colorstring (stdout, COL_NORMAL);
212
271
case EXIF_LOG_CODE_NO_MEMORY:
214
printf ("%s: ", domain);
215
vprintf (format, args);
272
case EXIF_LOG_CODE_CORRUPT_DATA:
273
put_colorstring (stderr, "\033[31;1m");
274
put_colorstring (stderr, "\033[31;4m");
275
fprintf (stderr, exif_log_code_get_title (code));
276
fprintf (stderr, "\n");
277
put_colorstring (stderr, "\033[;0m");
278
put_colorstring (stderr, COL_RED);
279
fprintf (stderr, exif_log_code_get_message (code));
280
fprintf (stderr, "\n");
281
fprintf (stderr, "%s: ", domain);
282
vfprintf (stderr, format, args);
283
put_colorstring (stderr, COL_NORMAL);
284
fprintf (stderr, "\n");
287
put_colorstring (stdout, COL_BLUE);
221
288
printf ("%s: ", domain);
222
289
vprintf (format, args);
290
put_colorstring (stdout, COL_NORMAL);
239
306
* these variables belong into main ().
241
308
static unsigned int list_tags = 0, show_description = 0, machine_readable = 0;
309
static unsigned int xml_output = 0;
242
310
static unsigned int extract_thumbnail = 0, remove_thumbnail = 0;
243
311
static unsigned int remove_tag = 0;
244
312
static unsigned int list_mnote = 0, debug = 0;
313
static unsigned int show_version = 0;
245
314
static const char *set_value = NULL, *ifd_string = NULL, *tag_string = NULL;
246
static ExifIfd ifd = -1;
315
static ExifIfd ifd = EXIF_IFD_0;
247
316
static ExifTag tag = 0;
248
317
static ExifOptions eo = {0, 0};
256
325
const char *ithumbnail = NULL;
257
326
struct poptOption options[] = {
328
{"version", 'v', POPT_ARG_NONE, &show_version, 0,
329
N_("Display software version"), NULL},
259
330
{"ids", 'i', POPT_ARG_NONE, &eo.use_ids, 0,
260
331
N_("Show IDs instead of tag names"), NULL},
261
332
{"tag", 't', POPT_ARG_STRING, &tag_string, 0,
283
354
{"machine-readable", 'm', POPT_ARG_NONE, &machine_readable, 0,
284
355
N_("Output in a machine-readable (tab delimited) format"),
357
{"xml-output", 'x', POPT_ARG_NONE, &xml_output, 0,
358
N_("Output in a XML format"),
286
360
{"debug", 'd', POPT_ARG_NONE, &debug, 0,
287
361
N_("Show debugging messages"), NULL},
304
378
poptSetOtherOptionHelp (ctx, _("[OPTION...] file"));
305
379
while (poptGetNextOpt (ctx) > 0);
308
log = exif_log_new ();
309
exif_log_set_func (log, log_func, NULL);
382
* When debugging, continue as far as possible. If not, make all errors
385
log = exif_log_new ();
386
exif_log_set_func (log, debug ? log_func : log_func_exit, NULL);
388
/* Any command line parameters ? */
314
390
poptPrintHelp (ctx, stdout, 0);
395
printf ("%s\n", VERSION);
400
ifd = exif_ifd_from_string (ifd_string);
401
if ((ifd < EXIF_IFD_0) || (ifd >= EXIF_IFD_COUNT) ||
402
!exif_ifd_get_name (ifd))
403
exif_log (log, -1, "exif", _("Invalid IFD '%s'. Valid IFDs are "
404
"'0', '1', 'EXIF', 'GPS', and "
405
"'Interoperability'."), ifd_string);
318
408
if (tag_string) {
319
409
tag = exif_tag_from_string (tag_string);
320
if (!tag || !exif_tag_get_name (tag)) {
321
fprintf (stderr, _("Invalid tag '%s'!"), tag_string);
322
fputc ('\n', stderr);
411
exif_log (log, -1, "exif", _("Invalid tag '%s'!"), tag_string);
329
ifd = exif_ifd_from_string (ifd_string);
330
if ((ifd < EXIF_IFD_0) || (ifd >= EXIF_IFD_COUNT) ||
331
!exif_ifd_get_name (ifd)) {
332
fprintf (stderr, _("Invalid IFD '%s'. Valid IFDs are "
333
"'0', '1', 'EXIF', 'GPS', and "
334
"'Interoperability'."), ifd_string);
335
fputc ('\n', stderr);
340
415
if (show_description) {
342
fprintf (stderr, _("Please specify a tag!"));
343
fputc ('\n', stderr);
416
if (!eo.tag) exif_log (log, -1, "exif", _("Please specify a tag!"));
346
417
printf (_("Tag '%s' (0x%04x, '%s'): %s"),
347
C(exif_tag_get_title (eo.tag)), eo.tag,
348
C(exif_tag_get_name (eo.tag)),
349
C(exif_tag_get_description (eo.tag)));
418
C(exif_tag_get_title_in_ifd (eo.tag, ifd)), eo.tag,
419
C(exif_tag_get_name_in_ifd (eo.tag, ifd)),
420
C(exif_tag_get_description_in_ifd (eo.tag, ifd)));
366
437
exif_loader_write_file (l, *args);
367
438
ed = exif_loader_get_data (l);
368
439
exif_loader_unref (l);
370
fprintf (stderr, _("'%s' does not "
371
"contain EXIF data!"), *args);
372
fputc ('\n', stderr);
440
if (!ed || ! (ed->data || ed->size ||
441
ed->ifd[EXIF_IFD_0]->count ||
442
ed->ifd[EXIF_IFD_1]->count ||
443
ed->ifd[EXIF_IFD_EXIF]->count ||
444
ed->ifd[EXIF_IFD_GPS]->count ||
445
ed->ifd[EXIF_IFD_INTEROPERABILITY]->count))
446
exif_log (log, -1, "exif", _("'%s' does not "
447
"contain EXIF data!"), *args);
376
449
/* Where do we save the output? */
377
450
memset (fname, 0, sizeof (fname));
387
460
action_tag_table (*args, ed);
388
} else if (tag && !set_value) {
461
} else if (tag && !set_value && !remove_tag) {
389
462
if ((ifd >= EXIF_IFD_0) &&
390
463
(ifd < EXIF_IFD_COUNT)) {
391
464
e = exif_content_get_entry (
392
465
ed->ifd[ifd], tag);
394
show_entry (e, ifd_string);
396
fprintf (stderr, _("IFD '%s' "
397
"does not contain tag "
399
ifd_string, tag_string);
400
fputc ('\n', stderr);
467
show_entry (e, machine_readable);
469
exif_log (log, -1, "exif", _("IFD '%s' "
470
"does not contain tag '%s'."), ifd_string, tag_string);
404
search_entry (ed, eo.tag);
472
search_entry (ed, eo.tag, machine_readable);
406
474
} else if (extract_thumbnail) {
408
476
/* No thumbnail? Exit. */
410
fprintf (stderr, _("'%s' does not "
411
"contain a thumbnail!"),
413
fputc ('\n', stderr);
478
exif_log (log, -1, "exif", _("'%s' does not "
479
"contain a thumbnail!"), *args);
417
481
/* Save the thumbnail */
418
482
f = fopen (fname, "wb");
485
exif_log (log, -1, "exif",
422
486
_("Could not open '%s' for "
423
487
"writing (%m)!"), fname);
489
exif_log (log, -1, "exif",
426
490
_("Could not open '%s' for "
427
491
"writing (%s)!"), fname,
428
492
strerror (errno));
430
fputc ('\n', stderr);
433
494
fwrite (ed->data, 1, ed->size, f);
435
496
fprintf (stdout, _("Wrote file '%s'."),
460
521
/* Insert new thumbnail */
461
522
f = fopen (ithumbnail, "rb");
464
fprintf (stderr, _("Could not open "
525
exif_log (log, -1, "exif", _("Could not open "
465
526
"'%s' (%m)!"), ithumbnail);
467
fprintf (stderr, _("Could not open "
528
exif_log (log, -1, "exif", _("Could not open "
468
529
"'%s' (%s)!"), ithumbnail,
469
530
strerror (errno));
471
fputc ('\n', stderr);
474
532
fseek (f, 0, SEEK_END);
475
533
ed->size = ftell (f);
476
534
ed->data = malloc (sizeof (char) * ed->size);
477
if (ed->size && !ed->data) {
478
fprintf (stderr, _("Could not "
479
"allocate %i byte(s)."),
481
fputc ('\n', stderr);
535
if (ed->size && !ed->data) EXIF_LOG_NO_MEMORY (log, "exif", ed->size);
484
536
fseek (f, 0, SEEK_SET);
485
537
if (fread (ed->data, sizeof (char),
486
ed->size, f) != ed->size) {
538
ed->size, f) != ed->size)
488
fprintf (stderr, _("Could not read "
540
exif_log (log, -1, "exif", _("Could not read "
489
541
"'%s' (%m)."), ithumbnail);
491
fprintf (stderr, _("Could not read "
543
exif_log (log, -1, "exif", _("Could not read "
492
544
"'%s' (%s)."), ithumbnail,
493
545
strerror (errno));
495
fputc ('\n', stderr);
500
save_exif_data_to_file (ed, *args, fname);
549
save_exif_data_to_file (ed, log, *args, fname);
502
551
} else if (set_value) {
504
553
/* We need a tag... */
506
fprintf (stderr, _("You need to "
508
fputc ('\n', stderr);
554
if (!tag) exif_log (log, -1, "exif", _("You need to specify a tag!"));
512
556
/* ... and an IFD. */
513
557
if ((ifd < EXIF_IFD_0) ||
514
(ifd >= EXIF_IFD_COUNT)) {
515
fprintf (stderr, _("You need to "
517
fputc ('\n', stderr);
558
(ifd >= EXIF_IFD_COUNT))
559
exif_log (log, -1, "exif", _("You need to specify an IFD!"));
521
561
/* If the entry doesn't exist, create it. */
522
562
e = exif_content_get_entry (ed->ifd[ifd], tag);
529
569
/* Now set the value and save the data. */
530
570
convert_arg_to_entry (set_value, e,
531
571
exif_data_get_byte_order (ed));
532
save_exif_data_to_file (ed, *args, fname);
572
save_exif_data_to_file (ed, log, *args, fname);
533
573
} else if (remove_tag) {
535
575
/* We need an IFD. */
536
576
if ((ifd < EXIF_IFD_0) ||
537
(ifd >= EXIF_IFD_COUNT)) {
538
fprintf (stderr, _("You need to "
540
fputc ('\n', stderr);
577
(ifd >= EXIF_IFD_COUNT))
578
exif_log (log, -1, "exif", _("You need to specify an IFD!"));
545
581
while (ed->ifd[ifd] &&
551
587
e = exif_content_get_entry (
552
588
ed->ifd[ifd], tag);
554
fprintf (stderr, _("IFD '%s' "
555
"does not contain a "
590
exif_log (log, -1, "exif", _("IFD '%s' does not contain a "
557
592
exif_ifd_get_name (ifd),
558
exif_tag_get_name (tag));
559
fputc ('\n', stderr);
562
exif_content_remove_entry (ed->ifd[ifd],
593
exif_tag_get_name_in_ifd (tag, ifd));
594
exif_content_remove_entry (ed->ifd[ifd], e);
566
597
/* Save modified data. */
567
save_exif_data_to_file (ed, *args, fname);
598
save_exif_data_to_file (ed, log, *args, fname);
569
600
} else if (machine_readable) {
570
601
action_tag_list_machine (*args, ed, eo.use_ids);
602
} else if (xml_output) {
603
action_tag_list_xml (*args, ed, eo.use_ids);
571
604
} else if (list_mnote) {
572
action_mnote_list (*args, ed);
605
action_mnote_list (*args, ed, eo.use_ids);
574
607
action_tag_list (*args, ed, eo.use_ids);
575
608
exif_data_unref (ed);
579
612
poptPrintHelp (ctx, stdout, 0);
581
616
poptFreeContext (ctx);