tool to fixes some issues in baseline tiffs (with extensions), see http://andreas-romeyke.de
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

112 lines
3.8 KiB

  1. /* fixes broken TIFF Files
  2. *
  3. * fixes wrong tagtypes of tags in Baseline-TIFFs,
  4. * based on http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html
  5. *
  6. * author: Andreas Romeyke, 2013-2017
  7. * licensed under conditions of libtiff
  8. */
  9. #include "fixit_tiff.h"
  10. #include "check_baseline.h"
  11. #include "tiff_helper.h"
  12. #include <tiffio.h>
  13. #include "tif_dir.h"
  14. const char * _tagtype( uint16 tagtype ) {
  15. switch (tagtype) {
  16. case TIFF_NOTYPE: return "NOTYPE"; break;
  17. case TIFF_BYTE: return "BYTE"; break;
  18. case TIFF_ASCII: return "ASCII"; break;
  19. case TIFF_SHORT: return "SHORT"; break;
  20. case TIFF_LONG: return "LONG"; break;
  21. case TIFF_RATIONAL: return "RATIONAL"; break;
  22. case TIFF_SBYTE: return "SBYTE"; break;
  23. case TIFF_UNDEFINED: return "UNDEFINED"; break;
  24. case TIFF_SSHORT: return "SSHORT"; break;
  25. case TIFF_SLONG: return "SLONG"; break;
  26. case TIFF_SRATIONAL: return "SRATIONAL"; break;
  27. case TIFF_FLOAT: return "FLOAT"; break;
  28. case TIFF_DOUBLE: return "DOUBLE"; break;
  29. case TIFF_IFD: return "IFD"; break;
  30. case TIFF_LONG8: return "LONG8"; break;
  31. case TIFF_SLONG8: return "SLONG8"; break;
  32. case TIFF_IFD8: return "IFD8"; break;
  33. default: return "unknown type"; break;
  34. }
  35. }
  36. void _replace_type(TIFF * tif, uint32 tag, uint16 found, uint16 newtype) {
  37. if (TIFFIsByteSwapped(tif))
  38. TIFFSwabShort(&newtype);
  39. printf("found fieldtype=%s (%i) for tag=%u, try to repair with type=%s (%i)\n", _tagtype(found), found, tag, _tagtype(newtype), newtype);
  40. /* via TIFFGetRawTagListEntry we have the tag
  41. * read, the next 2 bytes are the type */
  42. int fd = TIFFFileno( tif);
  43. if (write(fd, &newtype, 2) != 2) {
  44. perror("TIFF write error in IFD0");
  45. exit(EXIT_FAILURE);
  46. }
  47. if (0 != close(fd)) {
  48. perror("TIFF could not be closed");
  49. exit(EXIT_FAILURE);
  50. }
  51. }
  52. /** load a tiff, clean it up if needed, store tiff
  53. * @param filename filename which should be processed, repaired
  54. * only TAG 34665 (EXIFIFDOFFset) is supported yet
  55. */
  56. int cleanup_tagtype(const char * filename, uint32 tag_to_fix ) {
  57. /* load file */
  58. TIFF* tif = TIFFOpen(filename, "r+");
  59. if (NULL == tif) {
  60. fprintf( stderr, "file '%s' could not be opened\n", filename);
  61. exit (FIXIT_TIFF_READ_PERMISSION_ERROR);
  62. };
  63. uint32 tag_counter=TIFFGetRawTagListCount(tif);
  64. uint32 tagidx;
  65. uint32 tags[tag_counter];
  66. for (tagidx=0; tagidx < tag_counter; tagidx++) {
  67. uint32 tag = TIFFGetRawTagListEntry( tif, tagidx );
  68. if (tag == tag_to_fix) {
  69. if (FLAGGED == flag_be_verbose) printf("tag to fix %u\n", tags[tagidx]);
  70. const struct _TIFFField * fip = TIFFFieldWithTag(tif, tag);
  71. if (NULL == fip) {
  72. fprintf(stderr, "tagtype correction for tag %u fails, because requested tag does not exist (file '%s')\n", tag, filename);
  73. exit (FIXIT_TIFF_CMDLINE_ARGUMENTS_ERROR);
  74. }
  75. switch (tag) {
  76. case TIFFTAG_EXIFIFD:
  77. {
  78. uint16 found = fip->field_type;
  79. if (found != TIFF_LONG) {
  80. _replace_type(tif, tag, found, TIFF_LONG);
  81. goto EXIT;
  82. }
  83. break;
  84. }
  85. case TIFFTAG_RICHTIFFIPTC:
  86. {
  87. uint16 found = fip->field_type;
  88. if (found != TIFF_UNDEFINED && found != TIFF_BYTE) {
  89. _replace_type(tif, tag, found, TIFF_UNDEFINED);
  90. goto EXIT;
  91. }
  92. break;
  93. }
  94. default:
  95. fprintf(stderr, "tagtype correction for tag %u not supported yet (file '%s')\n", tag, filename);
  96. exit (FIXIT_TIFF_CMDLINE_ARGUMENTS_ERROR);
  97. }
  98. }
  99. }
  100. EXIT:
  101. if (FLAGGED == flag_be_verbose) printf("After correction\n-----------------\n");
  102. if (FIXIT_TIFF_IS_VALID == check_baseline (filename)) return FIXIT_TIFF_IS_CORRECTED;
  103. else return FIXIT_TIFF_IS_CHECKED;
  104. }
  105. /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/