From ae1d73fa41a988ace1c5f62268ab5f65e8d52b68 Mon Sep 17 00:00:00 2001 From: Martijn Braam Date: Sun, 27 Sep 2020 15:29:14 +0200 Subject: [PATCH] Write better EXIF data --- config/pine64,pinephone-1.0.ini | 3 ++ config/pine64,pinephone-1.1.ini | 3 ++ config/pine64,pinephone-1.2.ini | 3 ++ config/pine64,pinetab.ini | 3 ++ main.c | 55 ++++++++++++++++++++++++++++++--- 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/config/pine64,pinephone-1.0.ini b/config/pine64,pinephone-1.0.ini index 359e68a..cdb5c43 100644 --- a/config/pine64,pinephone-1.0.ini +++ b/config/pine64,pinephone-1.0.ini @@ -14,6 +14,9 @@ colormatrix=1.384,-0.3203,-0.0124,-0.2728,1.049,0.1556,-0.0506,0.2577,0.8050 forwardmatrix=0.7331,0.1294,0.1018,0.3039,0.6698,0.0263,0.0002,0.0556,0.7693 blacklevel=32 whitelevel=255 +focallength=3.33 +cropfactor=10.81 +fnumber=3.0 [front] driver=gc2145 diff --git a/config/pine64,pinephone-1.1.ini b/config/pine64,pinephone-1.1.ini index 359e68a..cdb5c43 100644 --- a/config/pine64,pinephone-1.1.ini +++ b/config/pine64,pinephone-1.1.ini @@ -14,6 +14,9 @@ colormatrix=1.384,-0.3203,-0.0124,-0.2728,1.049,0.1556,-0.0506,0.2577,0.8050 forwardmatrix=0.7331,0.1294,0.1018,0.3039,0.6698,0.0263,0.0002,0.0556,0.7693 blacklevel=32 whitelevel=255 +focallength=3.33 +cropfactor=10.81 +fnumber=3.0 [front] driver=gc2145 diff --git a/config/pine64,pinephone-1.2.ini b/config/pine64,pinephone-1.2.ini index 359e68a..cdb5c43 100644 --- a/config/pine64,pinephone-1.2.ini +++ b/config/pine64,pinephone-1.2.ini @@ -14,6 +14,9 @@ colormatrix=1.384,-0.3203,-0.0124,-0.2728,1.049,0.1556,-0.0506,0.2577,0.8050 forwardmatrix=0.7331,0.1294,0.1018,0.3039,0.6698,0.0263,0.0002,0.0556,0.7693 blacklevel=32 whitelevel=255 +focallength=3.33 +cropfactor=10.81 +fnumber=3.0 [front] driver=gc2145 diff --git a/config/pine64,pinetab.ini b/config/pine64,pinetab.ini index 359e68a..cdb5c43 100644 --- a/config/pine64,pinetab.ini +++ b/config/pine64,pinetab.ini @@ -14,6 +14,9 @@ colormatrix=1.384,-0.3203,-0.0124,-0.2728,1.049,0.1556,-0.0506,0.2577,0.8050 forwardmatrix=0.7331,0.1294,0.1018,0.3039,0.6698,0.0263,0.0002,0.0556,0.7693 blacklevel=32 whitelevel=255 +focallength=3.33 +cropfactor=10.81 +fnumber=3.0 [front] driver=gc2145 diff --git a/main.c b/main.c index dd55e8b..ab229bb 100644 --- a/main.c +++ b/main.c @@ -48,6 +48,10 @@ struct camerainfo { float forwardmatrix[9]; int blacklevel; int whitelevel; + + float focallength; + float cropfactor; + double fnumber; }; static float colormatrix_srgb[] = { @@ -372,6 +376,17 @@ init_device(int fd) return 0; } +static void +register_custom_tiff_tags(TIFF *tif) +{ + static const TIFFFieldInfo custom_fields[] = { + {TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, 1, 1, "ForwardMatrix1"}, + }; + + // Add missing dng fields + TIFFMergeFieldInfo(tif, custom_fields, sizeof(custom_fields) / sizeof(custom_fields[0])); +} + static void process_image(const int *p, int size) { @@ -391,11 +406,9 @@ process_image(const int *p, int size) TIFF *tif; int skip = 2; long sub_offset = 0; + uint64 exif_offset = 0; static const short cfapatterndim[] = {2, 2}; static const float neutral[] = {1.0, 1.0, 1.0}; - static const TIFFFieldInfo custom_fields[] = { - {TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, 1, 1, "ForwardMatrix1"}, - }; // Only process preview frames when not capturing if (capture == 0) { @@ -436,8 +449,6 @@ process_image(const int *p, int size) if(!(tif = TIFFOpen(fname, "w"))) { printf("Could not open tiff\n"); } - // Add missing dng fields - TIFFMergeFieldInfo(tif, custom_fields, sizeof(custom_fields) / sizeof(custom_fields[0])); // Define TIFF thumbnail TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 1); @@ -495,6 +506,7 @@ process_image(const int *p, int size) if(current.blacklevel) { TIFFSetField(tif, TIFFTAG_BLACKLEVEL, 1, ¤t.blacklevel); } + TIFFCheckpointDirectory(tif); printf("Writing frame\n"); unsigned char *pLine = (unsigned char*)malloc(current.width); @@ -502,6 +514,31 @@ process_image(const int *p, int size) TIFFWriteScanline(tif, ((uint8_t *)p)+(row*current.width), row, 0); } free(pLine); + TIFFWriteDirectory(tif); + + // Add an EXIF block to the tiff + TIFFCreateEXIFDirectory(tif); + // 1 = manual, 2 = full auto, 3 = aperture priority, 4 = shutter priority + TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 2); + TIFFSetField(tif, EXIFTAG_DATETIMEORIGINAL, datetime); + TIFFSetField(tif, EXIFTAG_DATETIMEDIGITIZED, datetime); + if(current.fnumber) { + TIFFSetField(tif, EXIFTAG_FNUMBER, current.fnumber); + } + if(current.focallength) { + TIFFSetField(tif, EXIFTAG_FOCALLENGTH, current.focallength); + } + if(current.focallength && current.cropfactor) { + TIFFSetField(tif, EXIFTAG_FOCALLENGTHIN35MMFILM, (short)(current.focallength * current.cropfactor)); + } + TIFFWriteCustomDirectory(tif, &exif_offset); + TIFFFreeDirectory(tif); + + // Update exif pointer + TIFFSetDirectory(tif, 0); + TIFFSetField(tif, TIFFTAG_EXIFIFD, exif_offset); + TIFFRewriteDirectory(tif); + TIFFClose(tif); @@ -702,6 +739,12 @@ config_ini_handler(void *user, const char *section, const char *name, cc->whitelevel = strtoint(value, NULL, 10); } else if (strcmp(name, "blacklevel") == 0) { cc->blacklevel = strtoint(value, NULL, 10); + } else if (strcmp(name, "focallength") == 0) { + cc->focallength = strtof(value, NULL); + } else if (strcmp(name, "cropfactor") == 0) { + cc->cropfactor = strtof(value, NULL); + } else if (strcmp(name, "fnumber") == 0) { + cc->fnumber = strtod(value, NULL); } else { g_printerr("Unknown key '%s' in [%s]\n", name, section); exit(1); @@ -1021,6 +1064,8 @@ main(int argc, char *argv[]) find_config(conffile); + TIFFSetTagExtender(register_custom_tiff_tags); + gtk_init(&argc, &argv); g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", TRUE, NULL); GtkBuilder *builder = gtk_builder_new_from_resource("/org/postmarketos/Megapixels/camera.glade");