Permalink
Browse files

- added a repair option for wrong exififd-type

  • Loading branch information...
Andreas Romeyke
Andreas Romeyke committed Jan 5, 2017
1 parent 2aebfa2 commit f51f71d79c51f26d634d36e1901b078aa4084501
Showing with 389 additions and 2 deletions.
  1. +65 −0 src/cleanup_tagtypes.c
  2. +14 −1 src/fixit_tiff.c
  3. +2 −1 src/fixit_tiff.h
  4. +308 −0 src/tif_dir.h
View
@@ -0,0 +1,65 @@
+/* fixes broken TIFF Files
+ *
+ * fixes wrong tagtypes of tags in Baseline-TIFFs,
+ * based on http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html
+ *
+ * author: Andreas Romeyke, 2013-2017
+ * licensed under conditions of libtiff
+ */
+
+
+#include "fixit_tiff.h"
+#include "check_baseline.h"
+#include "tiff_helper.h"
+#include <tiffio.h>
+#include "tif_dir.h"
+/** load a tiff, clean it up if needed, store tiff
+ * @param filename filename which should be processed, repaired
+ * only TAG 34665 (EXIFIFDOFFset) is supported yet
+ */
+int cleanup_tagtype(const char * filename, uint32 tag_to_fix ) {
+ /* load file */
+ TIFF* tif = TIFFOpen(filename, "r+");
+ if (NULL == tif) {
+ fprintf( stderr, "file '%s' could not be opened\n", filename);
+ exit (FIXIT_TIFF_READ_PERMISSION_ERROR);
+ };
+ uint32 tag_counter=TIFFGetRawTagListCount(tif);
+ uint32 tagidx;
+ uint32 tags[tag_counter];
+ for (tagidx=0; tagidx < tag_counter; tagidx++) {
+ uint32 tag = TIFFGetRawTagListEntry( tif, tagidx );
+ if (tag == tag_to_fix) {
+ if (FLAGGED == flag_be_verbose) printf("tag to fix %i\n", tags[tagidx]);
+ const struct _TIFFField * fip = TIFFFieldWithTag(tif, tag);
+ if (NULL == fip) {
+ fprintf(stderr, "tagtype correction for tag %i fails, because requested tag does not exist (file '%s')\n", tag, filename);
+ exit (FIXIT_TIFF_CMDLINE_ARGUMENTS_ERROR);
+ }
+ switch (tag) {
+ case TIFFTAG_EXIFIFD:
+ {
+ uint16 found = fip->field_type;
+ if (found != TIFF_LONG) {
+ uint16 newtype = TIFF_LONG;
+ printf("found fieldtype=%i for tag=%i, try to repair with type=%i\n", found, tag, newtype);
+ /* via TIFFGetRawTagListEntry we have the tag
+ * read, the next 2 bytes are the type */
+ int fd = TIFFFileno( tif);
+ write(fd, &newtype, sizeof( uint16));
+ close(fd);
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "tagtype correction for tag %i not supported yet (file '%s')\n", tag, filename);
+ exit (FIXIT_TIFF_CMDLINE_ARGUMENTS_ERROR);
+ }
+ }
+ }
+ if (FLAGGED == flag_be_verbose) printf("After correction\n-----------------\n");
+ /* write data back, only if no flag_check_only is set */
+ if (FIXIT_TIFF_IS_VALID == check_baseline (filename)) return FIXIT_TIFF_IS_CORRECTED;
+ else return FIXIT_TIFF_IS_CHECKED;
+}
+
View
@@ -27,6 +27,7 @@ void help () {
printf ("\t-t try to fix tagorder (dangerous)\n");
printf ("\t-x tag clean tiff from given tag\n");
printf ("\t-p try to repair ICC header profile\n");
+ printf ("\t-e try to repair wrong tagtype\n");
printf ("\tHint: 'fixit_tiff -i <infile> -o <outfile>' repairs date only\n");
}
@@ -72,9 +73,10 @@ int main (int argc, char * argv[]) {
int flag_tagorder=UNFLAGGED;
int flag_clean_icc=UNFLAGGED;
int flag_check_only=UNFLAGGED;
+ int flag_fix_tagtypes=UNFLAGGED;
int clean_tag=UNFLAGGED;
flag_be_verbose = FLAGGED;
- while ((c = getopt (argc, argv, "s::cbqtp::hi:o:x:")) != -1) {
+ while ((c = getopt (argc, argv, "s::cbqtp::hi:o:x:e")) != -1) {
switch (c)
{
case 'h': /* help */
@@ -107,6 +109,9 @@ int main (int argc, char * argv[]) {
case 'p': /* try to clean ICC header */
flag_clean_icc = FLAGGED;
break;
+ case 'e': /* try to fix tag type */
+ flag_fix_tagtypes = FLAGGED;
+ break;
case '?': /* something goes wrong */
if (optopt == 'i' || optopt == 'o' || optopt == 'x')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
@@ -170,6 +175,14 @@ int main (int argc, char * argv[]) {
cleanup_icc_header(outfilename);
exit (FIXIT_TIFF_IS_CORRECTED);
}
+ /* try to fix tag types */
+ if (FLAGGED == flag_fix_tagtypes) {
+ copy_file (infilename, outfilename);
+ if (FLAGGED == flag_be_verbose) printf ("fix tagtypes cleanup infile='%s', outfile='%s'\n", infilename, outfilename);
+ cleanup_tagtype(outfilename, 34665); // EXIFIFDOFFSET
+ exit (FIXIT_TIFF_IS_CORRECTED);
+ }
+
if (UNFLAGGED != clean_tag) { /* explicite correction via source target, clean given tag */
copy_file (infilename, outfilename);
View
@@ -29,9 +29,10 @@
int cleanup_datetime (const char *);
int cleanup_icc_header (const char *);
-int cleanup_baseline (const char *);
+int cleanup_baseline (const char *);
int cleanup_tagorder (const char *);
int cleanup_tag (const char *, uint32);
+int cleanup_tagtype (const char *, uint32);
#define FLAGGED 1
#define UNFLAGGED 0
Oops, something went wrong.

0 comments on commit f51f71d

Please sign in to comment.