1b8bc0d8aSopenharmony_ci/** \file test-extract.c 2b8bc0d8aSopenharmony_ci * \brief Extract EXIF data from a file and write it to another file. 3b8bc0d8aSopenharmony_ci * 4b8bc0d8aSopenharmony_ci * Copyright (C) 2019 Dan Fandrich <dan@coneharvesters.com> 5b8bc0d8aSopenharmony_ci * 6b8bc0d8aSopenharmony_ci * This library is free software; you can redistribute it and/or 7b8bc0d8aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8b8bc0d8aSopenharmony_ci * License as published by the Free Software Foundation; either 9b8bc0d8aSopenharmony_ci * version 2 of the License, or (at your option) any later version. 10b8bc0d8aSopenharmony_ci * 11b8bc0d8aSopenharmony_ci * This library is distributed in the hope that it will be useful, 12b8bc0d8aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13b8bc0d8aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14b8bc0d8aSopenharmony_ci * Lesser General Public License for more details. 15b8bc0d8aSopenharmony_ci * 16b8bc0d8aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17b8bc0d8aSopenharmony_ci * License along with this library; if not, write to the 18b8bc0d8aSopenharmony_ci * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19b8bc0d8aSopenharmony_ci * Boston, MA 02110-1301 USA. 20b8bc0d8aSopenharmony_ci * 21b8bc0d8aSopenharmony_ci */ 22b8bc0d8aSopenharmony_ci 23b8bc0d8aSopenharmony_ci#include "libexif/exif-data.h" 24b8bc0d8aSopenharmony_ci 25b8bc0d8aSopenharmony_ci#include <string.h> 26b8bc0d8aSopenharmony_ci#include <stdio.h> 27b8bc0d8aSopenharmony_ci#include <stdlib.h> 28b8bc0d8aSopenharmony_ci 29b8bc0d8aSopenharmony_ci 30b8bc0d8aSopenharmony_cistatic const unsigned char header[4] = {'\xff', '\xd8', '\xff', '\xe1'}; 31b8bc0d8aSopenharmony_ci 32b8bc0d8aSopenharmony_ciint main(const int argc, const char *argv[]) 33b8bc0d8aSopenharmony_ci{ 34b8bc0d8aSopenharmony_ci int first = 1; 35b8bc0d8aSopenharmony_ci const char *fn = "input.jpg"; 36b8bc0d8aSopenharmony_ci const char *outfn = "output.exif"; 37b8bc0d8aSopenharmony_ci ExifData *d; 38b8bc0d8aSopenharmony_ci unsigned char *buf; 39b8bc0d8aSopenharmony_ci unsigned int len; 40b8bc0d8aSopenharmony_ci FILE *f; 41b8bc0d8aSopenharmony_ci unsigned char lenbuf[2]; 42b8bc0d8aSopenharmony_ci 43b8bc0d8aSopenharmony_ci if (argc > 1 && !strcmp(argv[1], "-o")) { 44b8bc0d8aSopenharmony_ci outfn = argv[2]; 45b8bc0d8aSopenharmony_ci first += 2; 46b8bc0d8aSopenharmony_ci } 47b8bc0d8aSopenharmony_ci if (argc > first) { 48b8bc0d8aSopenharmony_ci fn = argv[first]; 49b8bc0d8aSopenharmony_ci ++first; 50b8bc0d8aSopenharmony_ci } 51b8bc0d8aSopenharmony_ci if (argc > first) { 52b8bc0d8aSopenharmony_ci fprintf (stderr, "Too many arguments\n"); 53b8bc0d8aSopenharmony_ci return 1; 54b8bc0d8aSopenharmony_ci } 55b8bc0d8aSopenharmony_ci 56b8bc0d8aSopenharmony_ci d = exif_data_new_from_file(fn); 57b8bc0d8aSopenharmony_ci if (!d) { 58b8bc0d8aSopenharmony_ci fprintf (stderr, "Could not load data from '%s'!\n", fn); 59b8bc0d8aSopenharmony_ci return 1; 60b8bc0d8aSopenharmony_ci } 61b8bc0d8aSopenharmony_ci 62b8bc0d8aSopenharmony_ci exif_data_save_data(d, &buf, &len); 63b8bc0d8aSopenharmony_ci exif_data_unref(d); 64b8bc0d8aSopenharmony_ci 65b8bc0d8aSopenharmony_ci if (!buf) { 66b8bc0d8aSopenharmony_ci fprintf (stderr, "Could not extract EXIF data!\n"); 67b8bc0d8aSopenharmony_ci return 2; 68b8bc0d8aSopenharmony_ci } 69b8bc0d8aSopenharmony_ci 70b8bc0d8aSopenharmony_ci f = fopen(outfn, "wb"); 71b8bc0d8aSopenharmony_ci if (!f) { 72b8bc0d8aSopenharmony_ci fprintf (stderr, "Could not open '%s' for writing!\n", outfn); 73b8bc0d8aSopenharmony_ci return 1; 74b8bc0d8aSopenharmony_ci } 75b8bc0d8aSopenharmony_ci /* Write EXIF with headers and length. */ 76b8bc0d8aSopenharmony_ci if (fwrite(header, 1, sizeof(header), f) != sizeof(header)) { 77b8bc0d8aSopenharmony_ci fprintf (stderr, "Could not write to '%s'!\n", outfn); 78b8bc0d8aSopenharmony_ci return 3; 79b8bc0d8aSopenharmony_ci } 80b8bc0d8aSopenharmony_ci /* 81b8bc0d8aSopenharmony_ci * FIXME: The buffer from exif_data_save_data() seems to contain extra 0xffd8 82b8bc0d8aSopenharmony_ci * 0xffd9 JPEG markers at the end that I wasn't expecting, making the length 83b8bc0d8aSopenharmony_ci * seem too long. Should those markers really be included? 84b8bc0d8aSopenharmony_ci */ 85b8bc0d8aSopenharmony_ci exif_set_short(lenbuf, EXIF_BYTE_ORDER_MOTOROLA, len); 86b8bc0d8aSopenharmony_ci if (fwrite(lenbuf, 1, 2, f) != 2) { 87b8bc0d8aSopenharmony_ci fprintf (stderr, "Could not write to '%s'!\n", outfn); 88b8bc0d8aSopenharmony_ci return 3; 89b8bc0d8aSopenharmony_ci } 90b8bc0d8aSopenharmony_ci if (fwrite(buf, 1, len, f) != len) { 91b8bc0d8aSopenharmony_ci fprintf (stderr, "Could not write to '%s'!\n", outfn); 92b8bc0d8aSopenharmony_ci return 3; 93b8bc0d8aSopenharmony_ci } 94b8bc0d8aSopenharmony_ci if (fclose(f) != 0) { 95b8bc0d8aSopenharmony_ci fprintf (stderr, "Could not close '%s'!\n", outfn); 96b8bc0d8aSopenharmony_ci return 3; 97b8bc0d8aSopenharmony_ci } 98b8bc0d8aSopenharmony_ci free(buf); 99b8bc0d8aSopenharmony_ci fprintf (stderr, "Wrote EXIF data to '%s'\n", outfn); 100b8bc0d8aSopenharmony_ci 101b8bc0d8aSopenharmony_ci return 0; 102b8bc0d8aSopenharmony_ci} 103