A tool to construct HDR-images from a series of exposures.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #include "exif.h"
  2. #include <iostream>
  3. #include <fstream>
  4. #include <stdint.h>
  5. #include <math.h>
  6. using namespace std;
  7. urational_t::urational_t(): p(0), q(0)
  8. {}
  9. urational_t::urational_t(uint32_t p, uint32_t q): p(p), q(q)
  10. {}
  11. srational_t::srational_t(): p(0), q(0)
  12. {}
  13. srational_t::srational_t(int32_t p, int32_t q): p(p), q(q)
  14. {}
  15. ExifTags::ExifTags():
  16. ifd0_parsed_ok(false),
  17. exififd_parsed_ok(false),
  18. exififd_offset(0)
  19. {
  20. }
  21. static uint16_t read_be_uint16(istream &stream) {
  22. unsigned char buf[2];
  23. stream.read((char*)buf, 2);
  24. return ((uint16_t)buf[0]) * 256 + (uint16_t)buf[1];
  25. }
  26. static uint16_t read_le_uint16(istream &stream) {
  27. unsigned char buf[2];
  28. stream.read((char*)buf, 2);
  29. return (uint16_t)buf[0] + ((uint16_t)buf[1]) * 256;
  30. }
  31. static uint16_t read_uint16(istream &stream, bool is_little_endian) {
  32. if (is_little_endian) {
  33. return read_le_uint16(stream);
  34. } else {
  35. return read_be_uint16(stream);
  36. }
  37. }
  38. static uint32_t read_be_uint32(istream &stream) {
  39. unsigned char buf[4];
  40. stream.read((char*)buf, 4);
  41. return ((uint32_t)buf[0]) * 16777216 +
  42. ((uint32_t)buf[1]) * 65536 +
  43. ((uint32_t)buf[2]) * 256 +
  44. (uint32_t)buf[3];
  45. }
  46. static uint32_t read_le_uint32(istream &stream) {
  47. unsigned char buf[4];
  48. stream.read((char*)buf, 4);
  49. return ((uint32_t)buf[3]) * 16777216 +
  50. ((uint32_t)buf[2]) * 65536 +
  51. ((uint32_t)buf[1]) * 256 +
  52. (uint32_t)buf[0];
  53. }
  54. static uint32_t read_uint32(istream &stream, bool is_little_endian) {
  55. if (is_little_endian) {
  56. return read_le_uint32(stream);
  57. } else {
  58. return read_be_uint32(stream);
  59. }
  60. }
  61. static int32_t read_be_int32(istream &stream) {
  62. unsigned char buf[4];
  63. stream.read((char*)buf, 4);
  64. return (int32_t)(((uint32_t)buf[0]) * 16777216 +
  65. ((uint32_t)buf[1]) * 65536 +
  66. ((uint32_t)buf[2]) * 256 +
  67. (uint32_t)buf[3]);
  68. }
  69. static int32_t read_le_int32(istream &stream) {
  70. unsigned char buf[4];
  71. stream.read((char*)buf, 4);
  72. return (int32_t)(((uint32_t)buf[3]) * 16777216 +
  73. ((uint32_t)buf[2]) * 65536 +
  74. ((uint32_t)buf[1]) * 256 +
  75. (uint32_t)buf[0]);
  76. }
  77. /*
  78. static int32_t read_int32(istream &stream, bool is_little_endian) {
  79. if (is_little_endian) {
  80. return read_le_int32(stream);
  81. } else {
  82. return read_be_int32(stream);
  83. }
  84. }
  85. */
  86. static urational_t read_urational(istream &stream, bool is_little_endian) {
  87. if (is_little_endian) {
  88. uint32_t p = read_le_uint32(stream);
  89. uint32_t q = read_le_uint32(stream);
  90. return urational_t(p, q);
  91. } else {
  92. uint32_t p = read_be_uint32(stream);
  93. uint32_t q = read_be_uint32(stream);
  94. return urational_t(p, q);
  95. }
  96. }
  97. static srational_t read_srational(istream &stream, bool is_little_endian) {
  98. if (is_little_endian) {
  99. int32_t p = read_le_int32(stream);
  100. int32_t q = read_le_int32(stream);
  101. return srational_t(p, q);
  102. } else {
  103. int32_t p = read_be_int32(stream);
  104. int32_t q = read_be_int32(stream);
  105. return srational_t(p, q);
  106. }
  107. }
  108. static bool read_exif_tags(istream &stream,
  109. unsigned int num_entries,
  110. ExifTags &tags,
  111. uint64_t tiff_start_pos,
  112. bool is_little_endian)
  113. {
  114. for (unsigned int i = 0; i < num_entries; i++) {
  115. uint16_t tag_num = read_uint16(stream, is_little_endian);
  116. uint16_t data_format = read_uint16(stream, is_little_endian);
  117. uint32_t num_components = read_uint32(stream, is_little_endian);
  118. uint32_t tag_data = read_uint32(stream, is_little_endian);
  119. if (tag_num == 34665) {
  120. if (data_format == 4 && num_components == 1) {
  121. if (tag_data > 65535) {
  122. cerr << "Exif IFD offset too big (" << tag_data << ")." << endl;
  123. return false;
  124. }
  125. tags.exififd_offset = tag_data;
  126. } else {
  127. cerr << "Exif IFD offset has strange format." << endl;
  128. return false;
  129. }
  130. }
  131. if (tag_num == 0x829a) {
  132. uint64_t cur = stream.tellg();
  133. stream.seekg(tiff_start_pos + tag_data, std::ios_base::beg);
  134. tags.exposure_time = read_urational(stream, is_little_endian);
  135. stream.seekg(cur, std::ios_base::beg);
  136. }
  137. if (tag_num == 0x9201) {
  138. uint64_t cur = stream.tellg();
  139. stream.seekg(tiff_start_pos + tag_data, std::ios_base::beg);
  140. tags.shutter_speed_value = read_srational(stream, is_little_endian);
  141. stream.seekg(cur, std::ios_base::beg);
  142. }
  143. }
  144. return true;
  145. }
  146. static bool read_exif_ifd(istream &stream,
  147. uint64_t tiff_start_pos,
  148. uint16_t ifd_offset,
  149. ExifTags &tags,
  150. bool is_little_endian)
  151. {
  152. if (ifd_offset == 0) {
  153. return true;
  154. }
  155. {
  156. uint64_t cur = stream.tellg();
  157. if (cur < tiff_start_pos) {
  158. cerr << "Read backwards?" << endl;
  159. return false;
  160. }
  161. if (ifd_offset < (cur - tiff_start_pos)) {
  162. cerr << "IFD offset too small." << endl;
  163. return false;
  164. }
  165. }
  166. stream.seekg(tiff_start_pos + ifd_offset, std::ios_base::beg);
  167. uint16_t num_entries = read_le_uint16(stream);
  168. return read_exif_tags(stream, num_entries, tags, tiff_start_pos, is_little_endian);
  169. }
  170. static bool parse_exif(istream &stream, uint16_t length, ExifTags &output) {
  171. if (length < 8) {
  172. return false;
  173. }
  174. {
  175. char buf[6];
  176. const char *compare = "Exif\0\0";
  177. stream.read(buf, 6);
  178. for (unsigned int i = 0; i < 6; i++) {
  179. if (buf[i] != compare[i]) {
  180. return false;
  181. }
  182. }
  183. }
  184. uint64_t tiff_start_pos = stream.tellg();
  185. bool is_little_endian = false;
  186. {
  187. char buf[2];
  188. stream.read(buf, 2);
  189. if (buf[0] == 'I' && buf[1] == 'I') {
  190. is_little_endian = true;
  191. } else if (buf[0] == 'M' && buf[1] == 'M') {
  192. is_little_endian = false;
  193. } else {
  194. cerr << "Endian fail" << endl;
  195. return false;
  196. }
  197. }
  198. {
  199. uint16_t magic = read_uint16(stream, is_little_endian);
  200. if (magic != 0x002a) {
  201. cerr << "TIFF fail" << endl;
  202. return false;
  203. }
  204. }
  205. uint32_t ifd0_offset = read_uint32(stream, is_little_endian);
  206. // Read IFD0
  207. output.ifd0_parsed_ok = read_exif_ifd(stream, tiff_start_pos, ifd0_offset, output, is_little_endian);
  208. if (output.exififd_offset != 0) {
  209. // Read Exif IFD
  210. output.exififd_parsed_ok = read_exif_ifd(stream, tiff_start_pos, output.exififd_offset, output, is_little_endian);
  211. }
  212. if (stream.fail()) {
  213. cerr << "stream failed" << endl;
  214. return false;
  215. } else {
  216. return true;
  217. }
  218. }
  219. bool ExifTags::read_from_jpeg(istream &stream, ExifTags &output) {
  220. unsigned char buf[2];
  221. stream.read((char*)buf, 2);
  222. if (!(buf[0] == 0xff && buf[1] == 0xd8)) {
  223. return false;
  224. }
  225. while (stream.good()) {
  226. stream.read((char*)buf, 2);
  227. if (buf[0] != 0xff) {
  228. cerr << "not a tag" << endl;
  229. return false;
  230. }
  231. if (buf[1] == 0xff || buf[1] == 0x00) {
  232. cerr << "not a marker" << endl;
  233. return false;
  234. }
  235. if (buf[1] == 0xd9) {
  236. break;
  237. }
  238. if (buf[1] == 0xda || (buf[1] >= 0xd0 && buf[1] <= 0xd7)) {
  239. // SOS marker or segment without length
  240. unsigned char c = 0;
  241. while(stream.good()) {
  242. c = stream.get();
  243. if (c == 0xff) {
  244. c = stream.get();
  245. if (c != 0x00) {
  246. // end of section
  247. stream.seekg(-2, std::ios_base::cur);
  248. break;
  249. }
  250. }
  251. }
  252. } else {
  253. // read size, seek to next marker
  254. uint16_t s = read_be_uint16(stream);
  255. if (s < 2) {
  256. cerr << "invalid size" << endl;
  257. return false;
  258. }
  259. if (buf[1] == 0xe1) {
  260. return parse_exif(stream, s, output);
  261. }
  262. stream.seekg(s - 2, std::ios_base::cur);
  263. }
  264. }
  265. if (stream.fail()) {
  266. cerr << "stream failed" << endl;
  267. return false;
  268. } else {
  269. return true;
  270. }
  271. }
  272. bool ExifTags::get_exposure_time(double &output) {
  273. if (exposure_time.p != 0 or exposure_time.q != 0) {
  274. output = (double)exposure_time.p / (double)exposure_time.q;
  275. return true;
  276. } else if (shutter_speed_value.p != 0 or shutter_speed_value.q != 0) {
  277. output = 1.0 / pow(2.0, (double)shutter_speed_value.p / (double)shutter_speed_value.q);
  278. return true;
  279. } else {
  280. return false;
  281. }
  282. }