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