treciprocity.c - filmtools - various tools for photographic film development and darkroom printing
(HTM) git clone git://src.adamsgaard.dk/filmtools
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) LICENSE
---
treciprocity.c (2131B)
---
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <err.h>
4 #include <math.h>
5 #include <string.h>
6
7 #define LENGTH(X) (sizeof X / sizeof X[0])
8
9 typedef struct {
10 const char *manufacturer;
11 const char *name;
12 double factor;
13 double exponent;
14 } Film;
15
16 static const Film films[] = {
17 { "ilford", "panf", 1.00, 1.33 },
18 { "ilford", "fp4", 1.00, 1.26 },
19 { "ilford", "hp5", 1.00, 1.31 },
20 { "ilford", "delta100", 1.00, 1.26 },
21 { "ilford", "delta400", 1.00, 1.41 },
22 { "ilford", "delta3200", 1.00, 1.33 },
23 { "ilford", "sfx", 1.00, 1.43 },
24 { "ilford", "xp2", 1.00, 1.31 },
25 { "fujifilm", "acros", 0.96, 1.02 },
26 { "kodak", "tmx", 1.18, 1.13 },
27 { "kodak", "tmy", 1.05, 1.22 },
28 { "kodak", "tmz", 1.34, 1.20 },
29 { "kodak", "trix", 2.41, 1.29 },
30 };
31
32 char *argv0;
33
34 static void
35 usage()
36 {
37 int i;
38
39 printf("usage: %s film time\n", argv0);
40 puts("where time is metered exposure time in seconds or format MM:SS,");
41 puts("and film is one of the following:");
42 for (i = 0; i < LENGTH(films); i++)
43 printf(" %-12s (%s)\n", films[i].name, films[i].manufacturer);
44 }
45
46 int
47 main(int argc, char **argv)
48 {
49 double factor, exponent, sec_equiv;
50 int i, hour, min, sec;
51
52 argv0 = *argv;
53
54 #ifdef __OpenBSD__
55 if (pledge("stdio", NULL) == -1)
56 errx(1, "pledge");
57 #endif
58
59 if (argc != 3) {
60 usage();
61 errx(1, "incorrect arguments");
62 }
63
64 for (i = 0;; i++) {
65 if (i == LENGTH(films))
66 errx(3, "unknown film type");
67 if (strncasecmp(argv[1], films[i].name, 10) == 0) {
68 factor = films[i].factor;
69 exponent = films[i].exponent;
70 break;
71 }
72 }
73
74 if (sscanf(argv[2], "%d:%d", &min, &sec) != 2) {
75 if (sscanf(argv[2], "%d", &sec) == 1) {
76 min = 0;
77 } else {
78 errx(2, "could not parse time in seconds or MM:SS format");
79 }
80 }
81
82 sec_equiv = factor * pow(min * 60 + sec, exponent);
83 sec = (int)(sec_equiv) % 60;
84 if ((min = (int)(sec_equiv / 60.0)) >= 60) {
85 hour = (int)(min/60.0);
86 min -= (int)(hour*60.0);
87 printf("%d:%02d:%02d\n", hour, min, sec);
88 } else {
89 printf("%d:%02d\n", min, sec);
90 }
91
92 return 0;
93 }