/src/FreeImage/Source/Metadata/XTIFF.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 661 lines · 438 code · 111 blank · 112 comment · 108 complexity · 465348e31b471aa45273d03c75e70773 MD5 · raw file

  1. // ==========================================================
  2. // Metadata functions implementation
  3. // Extended TIFF Directory GEO Tag Support
  4. //
  5. // Design and implementation by
  6. // - Hervé Drolon (drolon@infonie.fr)
  7. // - Thorsten Radde (support@IdealSoftware.com)
  8. // - Berend Engelbrecht (softwarecave@users.sourceforge.net)
  9. // - Mihail Naydenov (mnaydenov@users.sourceforge.net)
  10. //
  11. // Based on the LibTIFF xtiffio sample and on LibGeoTIFF
  12. //
  13. // This file is part of FreeImage 3
  14. //
  15. // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
  16. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
  17. // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
  18. // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
  19. // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
  20. // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
  21. // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
  22. // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
  23. // THIS DISCLAIMER.
  24. //
  25. // Use at your own risk!
  26. // ==========================================================
  27. #ifdef _MSC_VER
  28. #pragma warning (disable : 4786) // identifier was truncated to 'number' characters
  29. #endif
  30. #include "../LibTIFF4/tiffiop.h"
  31. #include "FreeImage.h"
  32. #include "Utilities.h"
  33. #include "FreeImageTag.h"
  34. #include "FIRational.h"
  35. // ----------------------------------------------------------
  36. // Extended TIFF Directory GEO Tag Support
  37. // ----------------------------------------------------------
  38. /**
  39. Tiff info structure.
  40. Entry format:
  41. { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM, OkToChange, PassDirCountOnSet, AsciiName }
  42. For ReadCount, WriteCount, -1 = unknown.
  43. */
  44. static const TIFFFieldInfo xtiffFieldInfo[] = {
  45. { TIFFTAG_GEOPIXELSCALE, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoPixelScale" },
  46. { TIFFTAG_INTERGRAPH_MATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "Intergraph TransformationMatrix" },
  47. { TIFFTAG_GEOTRANSMATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoTransformationMatrix" },
  48. { TIFFTAG_GEOTIEPOINTS, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoTiePoints" },
  49. { TIFFTAG_GEOKEYDIRECTORY,-1,-1, TIFF_SHORT, FIELD_CUSTOM, TRUE, TRUE, "GeoKeyDirectory" },
  50. { TIFFTAG_GEODOUBLEPARAMS, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoDoubleParams" },
  51. { TIFFTAG_GEOASCIIPARAMS, -1, -1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, "GeoASCIIParams" },
  52. { TIFFTAG_JPL_CARTO_IFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, TRUE, TRUE, "JPL Carto IFD offset" } /** Don't use this! **/
  53. };
  54. static void
  55. _XTIFFLocalDefaultDirectory(TIFF *tif) {
  56. int tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
  57. // Install the extended Tag field info
  58. TIFFMergeFieldInfo(tif, xtiffFieldInfo, tag_size);
  59. }
  60. static TIFFExtendProc _ParentExtender;
  61. /**
  62. This is the callback procedure, and is
  63. called by the DefaultDirectory method
  64. every time a new TIFF directory is opened.
  65. */
  66. static void
  67. _XTIFFDefaultDirectory(TIFF *tif) {
  68. // set up our own defaults
  69. _XTIFFLocalDefaultDirectory(tif);
  70. /*
  71. Since an XTIFF client module may have overridden
  72. the default directory method, we call it now to
  73. allow it to set up the rest of its own methods.
  74. */
  75. if (_ParentExtender)
  76. (*_ParentExtender)(tif);
  77. }
  78. /**
  79. XTIFF Initializer -- sets up the callback procedure for the TIFF module
  80. */
  81. void
  82. XTIFFInitialize(void) {
  83. static int first_time = 1;
  84. if (! first_time)
  85. return; /* Been there. Done that. */
  86. first_time = 0;
  87. // Grab the inherited method and install
  88. _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
  89. }
  90. // ----------------------------------------------------------
  91. // GeoTIFF tag reading / writing
  92. // ----------------------------------------------------------
  93. void
  94. tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
  95. char defaultKey[16];
  96. size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
  97. TagLib& tag_lib = TagLib::instance();
  98. for(unsigned i = 0; i < tag_size; i++) {
  99. const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i];
  100. if(fieldInfo->field_type == TIFF_ASCII) {
  101. char *params = NULL;
  102. if(TIFFGetField(tif, fieldInfo->field_tag, &params)) {
  103. // create a tag
  104. FITAG *tag = FreeImage_CreateTag();
  105. if(!tag)
  106. return;
  107. WORD tag_id = (WORD)fieldInfo->field_tag;
  108. FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)fieldInfo->field_type);
  109. FreeImage_SetTagID(tag, tag_id);
  110. FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey));
  111. FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id));
  112. FreeImage_SetTagLength(tag, (DWORD)strlen(params) + 1);
  113. FreeImage_SetTagCount(tag, FreeImage_GetTagLength(tag));
  114. FreeImage_SetTagValue(tag, params);
  115. FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag);
  116. // delete the tag
  117. FreeImage_DeleteTag(tag);
  118. }
  119. } else {
  120. short tag_count = 0;
  121. void* data = NULL;
  122. if(TIFFGetField(tif, fieldInfo->field_tag, &tag_count, &data)) {
  123. // create a tag
  124. FITAG *tag = FreeImage_CreateTag();
  125. if(!tag)
  126. return;
  127. WORD tag_id = (WORD)fieldInfo->field_tag;
  128. FREE_IMAGE_MDTYPE tag_type = (FREE_IMAGE_MDTYPE)fieldInfo->field_type;
  129. FreeImage_SetTagType(tag, tag_type);
  130. FreeImage_SetTagID(tag, tag_id);
  131. FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey));
  132. FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id));
  133. FreeImage_SetTagLength(tag, FreeImage_TagDataWidth(tag_type) * tag_count);
  134. FreeImage_SetTagCount(tag, tag_count);
  135. FreeImage_SetTagValue(tag, data);
  136. FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag);
  137. // delete the tag
  138. FreeImage_DeleteTag(tag);
  139. }
  140. }
  141. } // for(tag_size)
  142. }
  143. void
  144. tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
  145. char defaultKey[16];
  146. if(FreeImage_GetMetadataCount(FIMD_GEOTIFF, dib) == 0) {
  147. return;
  148. }
  149. size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]);
  150. TagLib& tag_lib = TagLib::instance();
  151. for(unsigned i = 0; i < tag_size; i++) {
  152. const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i];
  153. FITAG *tag = NULL;
  154. const char *key = tag_lib.getTagFieldName(TagLib::GEOTIFF, (WORD)fieldInfo->field_tag, defaultKey);
  155. if(FreeImage_GetMetadata(FIMD_GEOTIFF, dib, key, &tag)) {
  156. if(FreeImage_GetTagType(tag) == FIDT_ASCII) {
  157. TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagValue(tag));
  158. } else {
  159. TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag));
  160. }
  161. }
  162. }
  163. }
  164. // ----------------------------------------------------------
  165. // EXIF tag reading & writing
  166. // ----------------------------------------------------------
  167. /**
  168. Read a single exif tag
  169. */
  170. static BOOL
  171. tiff_read_exif_tag(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib, TagLib& tagLib, TIFFDirectory *td, uint32 tag) {
  172. const TIFFField *fip;
  173. uint32 value_count;
  174. int mem_alloc = 0;
  175. void *raw_data = NULL;
  176. if(tag == TIFFTAG_EXIFIFD) {
  177. return TRUE;
  178. }
  179. // get the tag key - use NULL to avoid reading GeoTIFF tags
  180. const char *key = tagLib.getTagFieldName(md_model, (WORD)tag, NULL);
  181. if(key == NULL) {
  182. return TRUE;
  183. }
  184. fip = TIFFFieldWithTag(tif, tag);
  185. if(fip == NULL) {
  186. return TRUE;
  187. }
  188. if(fip->field_passcount) { //<- "passcount" means "returns count"
  189. if (fip->field_readcount != TIFF_VARIABLE2) { //<- TIFF_VARIABLE2 means "uses LONG count"
  190. // assume TIFF_VARIABLE (uses SHORT count)
  191. uint16 value_count16;
  192. if(TIFFGetField(tif, tag, &value_count16, &raw_data) != 1) {
  193. return TRUE;
  194. }
  195. value_count = value_count16;
  196. } else {
  197. if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) {
  198. return TRUE;
  199. }
  200. }
  201. } else {
  202. // determine count
  203. if (fip->field_readcount == TIFF_VARIABLE || fip->field_readcount == TIFF_VARIABLE2) {
  204. value_count = 1;
  205. } else if (fip->field_readcount == TIFF_SPP) {
  206. value_count = td->td_samplesperpixel;
  207. } else {
  208. value_count = fip->field_readcount;
  209. }
  210. // access fields as pointers to data
  211. // (### determining this is NOT robust... and hardly can be. It is implemented looking the _TIFFVGetField code)
  212. if(fip->field_tag == TIFFTAG_TRANSFERFUNCTION) {
  213. // reading this tag cause a bug probably located somewhere inside libtiff
  214. return TRUE;
  215. }
  216. if ((fip->field_type == TIFF_ASCII
  217. || fip->field_readcount == TIFF_VARIABLE
  218. || fip->field_readcount == TIFF_VARIABLE2
  219. || fip->field_readcount == TIFF_SPP
  220. || value_count > 1)
  221. && fip->field_tag != TIFFTAG_PAGENUMBER
  222. && fip->field_tag != TIFFTAG_HALFTONEHINTS
  223. && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
  224. && fip->field_tag != TIFFTAG_DOTRANGE
  225. && fip->field_tag != TIFFTAG_BITSPERSAMPLE //<- these two are tricky -
  226. && fip->field_tag != TIFFTAG_COMPRESSION //<- they are defined as TIFF_VARIABLE but in reality return a single value
  227. ) {
  228. if(TIFFGetField(tif, tag, &raw_data) != 1) {
  229. return TRUE;
  230. }
  231. } else {
  232. // access fields as values
  233. const int value_size = _TIFFDataSize(fip->field_type);
  234. raw_data = _TIFFmalloc(value_size * value_count);
  235. mem_alloc = 1;
  236. int ok = FALSE;
  237. // ### if value_count > 1, tag is PAGENUMBER or HALFTONEHINTS or YCBCRSUBSAMPLING or DOTRANGE,
  238. // all off which are value_count == 2 (see tif_dirinfo.c)
  239. switch(value_count)
  240. {
  241. case 1:
  242. ok = TIFFGetField(tif, tag, raw_data);
  243. break;
  244. case 2:
  245. ok = TIFFGetField(tif, tag, raw_data, (BYTE*)(raw_data) + value_size*1);
  246. break;
  247. /* # we might need more in the future:
  248. case 3:
  249. ok = TIFFGetField(tif, tag, raw_data, (BYTE*)(raw_data) + value_size*1, (BYTE*)(raw_data) + value_size*2);
  250. break;
  251. */
  252. default:
  253. FreeImage_OutputMessageProc(FIF_TIFF, "Unimplemented variable number of parameters for Tiff Tag %s", fip->field_name);
  254. break;
  255. }
  256. if(ok != 1) {
  257. _TIFFfree(raw_data);
  258. return TRUE;
  259. }
  260. }
  261. }
  262. // build FreeImage tag from Tiff Tag data we collected
  263. FITAG *fitag = FreeImage_CreateTag();
  264. if(!fitag) {
  265. if(mem_alloc) {
  266. _TIFFfree(raw_data);
  267. }
  268. return FALSE;
  269. }
  270. FreeImage_SetTagID(fitag, (WORD)tag);
  271. FreeImage_SetTagKey(fitag, key);
  272. switch(fip->field_type) {
  273. case TIFF_BYTE:
  274. FreeImage_SetTagType(fitag, FIDT_BYTE);
  275. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  276. FreeImage_SetTagCount(fitag, value_count);
  277. FreeImage_SetTagValue(fitag, raw_data);
  278. break;
  279. case TIFF_UNDEFINED:
  280. FreeImage_SetTagType(fitag, FIDT_UNDEFINED);
  281. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  282. FreeImage_SetTagCount(fitag, value_count);
  283. FreeImage_SetTagValue(fitag, raw_data);
  284. break;
  285. case TIFF_SBYTE:
  286. FreeImage_SetTagType(fitag, FIDT_SBYTE);
  287. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  288. FreeImage_SetTagCount(fitag, value_count);
  289. FreeImage_SetTagValue(fitag, raw_data);
  290. break;
  291. case TIFF_SHORT:
  292. FreeImage_SetTagType(fitag, FIDT_SHORT);
  293. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  294. FreeImage_SetTagCount(fitag, value_count);
  295. FreeImage_SetTagValue(fitag, raw_data);
  296. break;
  297. case TIFF_SSHORT:
  298. FreeImage_SetTagType(fitag, FIDT_SSHORT);
  299. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  300. FreeImage_SetTagCount(fitag, value_count);
  301. FreeImage_SetTagValue(fitag, raw_data);
  302. break;
  303. case TIFF_LONG:
  304. FreeImage_SetTagType(fitag, FIDT_LONG);
  305. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  306. FreeImage_SetTagCount(fitag, value_count);
  307. FreeImage_SetTagValue(fitag, raw_data);
  308. break;
  309. case TIFF_IFD:
  310. FreeImage_SetTagType(fitag, FIDT_IFD);
  311. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  312. FreeImage_SetTagCount(fitag, value_count);
  313. FreeImage_SetTagValue(fitag, raw_data);
  314. break;
  315. case TIFF_SLONG:
  316. FreeImage_SetTagType(fitag, FIDT_SLONG);
  317. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  318. FreeImage_SetTagCount(fitag, value_count);
  319. FreeImage_SetTagValue(fitag, raw_data);
  320. break;
  321. case TIFF_RATIONAL: {
  322. // LibTIFF converts rational to floats : reconvert floats to rationals
  323. DWORD *rvalue = (DWORD*)malloc(2 * value_count * sizeof(DWORD));
  324. for(uint32 i = 0; i < value_count; i++) {
  325. float *fv = (float*)raw_data;
  326. FIRational rational(fv[i]);
  327. rvalue[2*i] = rational.getNumerator();
  328. rvalue[2*i+1] = rational.getDenominator();
  329. }
  330. FreeImage_SetTagType(fitag, FIDT_RATIONAL);
  331. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  332. FreeImage_SetTagCount(fitag, value_count);
  333. FreeImage_SetTagValue(fitag, rvalue);
  334. free(rvalue);
  335. }
  336. break;
  337. case TIFF_SRATIONAL: {
  338. // LibTIFF converts rational to floats : reconvert floats to rationals
  339. LONG *rvalue = (LONG*)malloc(2 * value_count * sizeof(LONG));
  340. for(uint32 i = 0; i < value_count; i++) {
  341. float *fv = (float*)raw_data;
  342. FIRational rational(fv[i]);
  343. rvalue[2*i] = rational.getNumerator();
  344. rvalue[2*i+1] = rational.getDenominator();
  345. }
  346. FreeImage_SetTagType(fitag, FIDT_RATIONAL);
  347. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  348. FreeImage_SetTagCount(fitag, value_count);
  349. FreeImage_SetTagValue(fitag, rvalue);
  350. free(rvalue);
  351. }
  352. break;
  353. case TIFF_FLOAT:
  354. FreeImage_SetTagType(fitag, FIDT_FLOAT);
  355. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  356. FreeImage_SetTagCount(fitag, value_count);
  357. FreeImage_SetTagValue(fitag, raw_data);
  358. break;
  359. case TIFF_DOUBLE:
  360. FreeImage_SetTagType(fitag, FIDT_DOUBLE);
  361. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  362. FreeImage_SetTagCount(fitag, value_count);
  363. FreeImage_SetTagValue(fitag, raw_data);
  364. break;
  365. case TIFF_LONG8: // BigTIFF 64-bit unsigned integer
  366. FreeImage_SetTagType(fitag, FIDT_LONG8);
  367. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  368. FreeImage_SetTagCount(fitag, value_count);
  369. FreeImage_SetTagValue(fitag, raw_data);
  370. break;
  371. case TIFF_IFD8: // BigTIFF 64-bit unsigned integer (offset)
  372. FreeImage_SetTagType(fitag, FIDT_IFD8);
  373. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  374. FreeImage_SetTagCount(fitag, value_count);
  375. FreeImage_SetTagValue(fitag, raw_data);
  376. break;
  377. case TIFF_SLONG8: // BigTIFF 64-bit signed integer
  378. FreeImage_SetTagType(fitag, FIDT_SLONG8);
  379. FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
  380. FreeImage_SetTagCount(fitag, value_count);
  381. FreeImage_SetTagValue(fitag, raw_data);
  382. break;
  383. default: {
  384. size_t length = strlen((char*)raw_data) + 1;
  385. FreeImage_SetTagType(fitag, FIDT_ASCII);
  386. FreeImage_SetTagLength(fitag, (DWORD)length);
  387. FreeImage_SetTagCount(fitag, (DWORD)length);
  388. FreeImage_SetTagValue(fitag, raw_data);
  389. }
  390. break;
  391. }
  392. const char *description = tagLib.getTagDescription(md_model, (WORD)tag);
  393. if(description) {
  394. FreeImage_SetTagDescription(fitag, description);
  395. }
  396. // store the tag
  397. FreeImage_SetMetadata(tagLib.getFreeImageModel(md_model), dib, FreeImage_GetTagKey(fitag), fitag);
  398. // destroy the tag
  399. FreeImage_DeleteTag(fitag);
  400. if(mem_alloc) {
  401. _TIFFfree(raw_data);
  402. }
  403. return TRUE;
  404. }
  405. /**
  406. Read all known exif tags
  407. */
  408. BOOL
  409. tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
  410. int i;
  411. short count;
  412. TagLib& tagLib = TagLib::instance();
  413. TIFFDirectory *td = &tif->tif_dir;
  414. count = (short) TIFFGetTagListCount(tif);
  415. for(i = 0; i < count; i++) {
  416. uint32 tag = TIFFGetTagListEntry(tif, i);
  417. // read the tag
  418. if (!tiff_read_exif_tag(tif, md_model, dib, tagLib, td, tag))
  419. return FALSE;
  420. }
  421. // we want to know values of standard tags too!!
  422. // loop over all Core Directory Tags
  423. // ### uses private data, but there is no other way
  424. if(md_model == TagLib::EXIF_MAIN) {
  425. uint32 lastTag = 0; //<- used to prevent reading some tags twice (as stored in tif_fieldinfo)
  426. for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
  427. const TIFFField *fld = tif->tif_fields[fi];
  428. if(fld->field_tag == lastTag)
  429. continue;
  430. // test if tag value is set
  431. // (lifted directly form LibTiff _TIFFWriteDirectory)
  432. if( fld->field_bit == FIELD_CUSTOM ) {
  433. int ci, is_set = FALSE;
  434. for( ci = 0; ci < td->td_customValueCount; ci++ ) {
  435. is_set |= (td->td_customValues[ci].info == fld);
  436. }
  437. if( !is_set ) {
  438. continue;
  439. }
  440. } else if(!TIFFFieldSet(tif, fld->field_bit)) {
  441. continue;
  442. }
  443. // process *all* other tags (some will be ignored)
  444. tiff_read_exif_tag(tif, md_model, dib, tagLib, td, fld->field_tag);
  445. lastTag = fld->field_tag;
  446. }
  447. }
  448. return TRUE;
  449. }
  450. /**
  451. Skip tags that are already handled by the LibTIFF writing process
  452. */
  453. static BOOL
  454. skip_write_field(TIFF* tif, uint32 tag) {
  455. switch (tag) {
  456. case TIFFTAG_SAMPLEFORMAT:
  457. case TIFFTAG_IMAGEWIDTH:
  458. case TIFFTAG_IMAGELENGTH:
  459. case TIFFTAG_SAMPLESPERPIXEL:
  460. case TIFFTAG_BITSPERSAMPLE:
  461. case TIFFTAG_PHOTOMETRIC:
  462. case TIFFTAG_PLANARCONFIG:
  463. case TIFFTAG_ROWSPERSTRIP:
  464. case TIFFTAG_RESOLUTIONUNIT:
  465. case TIFFTAG_XRESOLUTION:
  466. case TIFFTAG_YRESOLUTION:
  467. case TIFFTAG_SUBFILETYPE:
  468. case TIFFTAG_PAGENUMBER:
  469. case TIFFTAG_COLORMAP:
  470. case TIFFTAG_ORIENTATION:
  471. case TIFFTAG_COMPRESSION:
  472. case TIFFTAG_PREDICTOR:
  473. case TIFFTAG_GROUP3OPTIONS:
  474. case TIFFTAG_FILLORDER:
  475. // skip always, values have been set in SaveOneTIFF()
  476. return TRUE;
  477. break;
  478. case TIFFTAG_RICHTIFFIPTC:
  479. // skip always, IPTC metadata model is set in tiff_write_iptc_profile()
  480. return TRUE;
  481. break;
  482. case TIFFTAG_YCBCRCOEFFICIENTS:
  483. case TIFFTAG_REFERENCEBLACKWHITE:
  484. case TIFFTAG_YCBCRSUBSAMPLING:
  485. // skip as they cannot be filled yet
  486. return TRUE;
  487. break;
  488. case TIFFTAG_PAGENAME:
  489. {
  490. char *value = NULL;
  491. TIFFGetField(tif, TIFFTAG_PAGENAME, &value);
  492. // only skip if no value has been set
  493. if(value == NULL) {
  494. return FALSE;
  495. } else {
  496. return TRUE;
  497. }
  498. }
  499. default:
  500. return FALSE;
  501. break;
  502. }
  503. }
  504. /**
  505. Write all known exif tags
  506. */
  507. BOOL
  508. tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
  509. char defaultKey[16];
  510. // only EXIF_MAIN so far
  511. if(md_model != TagLib::EXIF_MAIN) {
  512. return FALSE;
  513. }
  514. if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, dib) == 0) {
  515. return FALSE;
  516. }
  517. TagLib& tag_lib = TagLib::instance();
  518. for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
  519. const TIFFField *fld = tif->tif_fields[fi];
  520. if(skip_write_field(tif, fld->field_tag)) {
  521. // skip tags that are already handled by the LibTIFF writing process
  522. continue;
  523. }
  524. FITAG *tag = NULL;
  525. // get the tag key
  526. const char *key = tag_lib.getTagFieldName(TagLib::EXIF_MAIN, (WORD)fld->field_tag, defaultKey);
  527. if(FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, key, &tag)) {
  528. FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag);
  529. TIFFDataType tif_tag_type = fld->field_type;
  530. // check for identical formats
  531. // (enum value are the sames between FREE_IMAGE_MDTYPE and TIFFDataType types)
  532. if((int)tif_tag_type != (int)tag_type) {
  533. // skip tag or _TIFFmemcpy will fail
  534. continue;
  535. }
  536. // type of storage may differ (e.g. rationnal array vs float array type)
  537. if(_TIFFDataSize(tif_tag_type) != FreeImage_TagDataWidth(tag_type)) {
  538. // skip tag or _TIFFmemcpy will fail
  539. continue;
  540. }
  541. if(tag_type == FIDT_ASCII) {
  542. TIFFSetField(tif, fld->field_tag, FreeImage_GetTagValue(tag));
  543. } else {
  544. TIFFSetField(tif, fld->field_tag, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag));
  545. }
  546. }
  547. }
  548. return TRUE;
  549. }