Browse Source

- added new archeological tool print_ifd_at_adress

- moved find_potential_IFD_offsets to subdir src/archeological_tools/
- fixed CMAKELists.txt for target all
- extended "soft" checks in find_potential_IFD_offsets
- improved output in find_potential_IFD_offsets
tags/v0.1.2
Andreas Romeyke 2 years ago
parent
commit
dcfae6be07
3 changed files with 157 additions and 4 deletions
  1. +3
    -1
      src/CMakeLists.txt
  2. +40
    -3
      src/archeological_tools/find_potential_IFD_offsets.c
  3. +114
    -0
      src/archeological_tools/print_ifd_at_adress.c

+ 3
- 1
src/CMakeLists.txt View File

@@ -27,7 +27,8 @@ if(WIN32)
endif(WIN32)

add_executable(fixit_tiff fixit_tiff.c ${fixit_tiff_SOURCES})
add_executable(find_potential_IFD_offsets find_potential_IFD_offsets.c)
add_executable(find_potential_IFD_offsets archeological_tools/find_potential_IFD_offsets.c)
add_executable(print_ifd_at_adress archeological_tools/print_ifd_at_adress.c)
set(CMAKE_EXTRA_INCLUDE_FILES tiff.h)


@@ -97,6 +98,7 @@ endif(TIFF_FOUND)

TARGET_LINK_LIBRARIES(fixit_tiff ${TIFF_LIBRARIES})
TARGET_LINK_LIBRARIES(find_potential_IFD_offsets ${TIFF_LIBRARIES})
TARGET_LINK_LIBRARIES(print_ifd_at_adress ${TIFF_LIBRARIES})

install( TARGETS fixit_tiff
RUNTIME DESTINATION bin


src/find_potential_IFD_offsets.c → src/archeological_tools/find_potential_IFD_offsets.c View File

@@ -22,6 +22,7 @@
/* #include <sys\stat.h> */
#include <sys/stat.h>
#endif

/** help function */
void help () {
printf ("find_potential_IFD_offsets\n");
@@ -43,9 +44,14 @@ void scan_file_for_ifds(const char * infile, const char * outfile) {
if(fd_out == NULL) {
perror("could not open output file");
}
fprintf( fd_out, "#adress,weight,is_sorted,has_required_baseline\n");

uint32 filesize = lseek( fd_in, 0L, SEEK_END);
/* for each odd adress, do */
for (uint32 adress = 8; adress < filesize; adress+=2) {
if (adress % 1024 == 0) {
printf ("\r%li %%", (uint64) 100*adress/filesize);
}
lseek( fd_in, adress, SEEK_SET);
/* check if "count of tags" is greater 4 (hard criteria) */
uint16 countoftags = 0;
@@ -58,14 +64,19 @@ void scan_file_for_ifds(const char * infile, const char * outfile) {
lseek( fd_in, 12*countoftags, SEEK_CUR);
if (read(fd_in, &nextifd, 4) != 4) perror("input file not readable, nextifd");
if (nextifd % 2 == 0) {
printf("0x%0x countoftags=%i nextifd=%0x\n", adress, countoftags, nextifd);
//printf("0x%0x countoftags=%i nextifd=%0x\n", adress, countoftags, nextifd);
/* check for each "tag" if fieldtype is in range 1..18 (in original 12, but libtiff supports 18) (hard criteria) */
int tagids_ok = 0;
int fieldtypes_ok = 0;

int has_baselinetags[count_of_required_baselinetags];
for (int i = 0; i < count_of_required_baselinetags; i++) {
has_baselinetags[i]=0;
}
int sorted = 0;
lseek( fd_in, adress
+ 2 /* countoftags */
, SEEK_SET);
int last_tagid = 0;
for (int i = 1; i <countoftags; i++) {
uint16 tagid = 0;
uint16 fieldtype = 0;
@@ -74,19 +85,45 @@ printf("0x%0x countoftags=%i nextifd=%0x\n", adress, countoftags, nextifd);
}
if (read(fd_in, &tagid, 2) != 2) perror ("input file not readable, tagids");
if (tagid < 0x00fe) { tagids_ok = 1; break; }
if (last_tagid >= tagid) { sorted =1; }
last_tagid=tagid;
for (int j = 0; j < count_of_required_baselinetags; j++) {
if (tagid == required_baselinetags[j]) {
has_baselinetags[j]++;
}
}
if (read(fd_in, &fieldtype, 2) != 2) perror ("input file not readable, fieldtypes");
if (fieldtype < 1 || fieldtype > 18) { fieldtypes_ok = 1; break; }
}
if (tagids_ok == 0 && fieldtypes_ok == 0) {
/* do some soft checks if possible */
int weight = 0;
/*
* check if required tags are present (soft criteria)
* check for each "tag" if tagid is sorted (soft criteria)
* check for each "tag" if value/offset is a offset and this offset is odd
* and point to adress within file (soft criteria)
*/

/* check if required tags are present (soft criteria) */
int all_baselinetags = 0;
for (int j = 0; j < count_of_required_baselinetags; j++) {
if (has_baselinetags[j] == 1) {
all_baselinetags++;
}
}
if (all_baselinetags == count_of_required_baselinetags) {
weight++;
}
/* check for each "tag" if tagid is sorted (soft criteria) */
if (sorted == 0) { weight++; }
/* print result */
fprintf( fd_out, "0x%04x,\n", adress);
fprintf( fd_out, "0x%04x,%i,%c,%c\n",
adress,
weight,
(sorted==0)?'y':'n',
all_baselinetags==count_of_required_baselinetags?'y':'n'
);
}
}
}

+ 114
- 0
src/archeological_tools/print_ifd_at_adress.c View File

@@ -0,0 +1,114 @@
/*
* =====================================================================================
*
* Filename: print_ifds_at_adress.c
*
* Description: print a IFD on given adress
*
* Compiler: gcc
*
* Author: Andreas Romeyke, 2018
* licensed under conditions of libtiff
*
* =====================================================================================
*/
#include "fixit_tiff.h"
#include <fcntl.h>
#ifdef __unix__
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#else
/* #include <sys\stat.h> */
#include <sys/stat.h>
#endif

void print_ifd_at_adress (const char * infile, uint32 adress) {
/* open infile */
int fd_in = open(infile, O_RDWR );
if (! fd_in) {
perror("could not open input file");
}
uint32 filesize = lseek( fd_in, 0L, SEEK_END);
if (adress > filesize) {
fprintf(stderr, "Adress 0x%0x is outside of filesize (0x%0x", adress, filesize);
exit(0);
}
lseek( fd_in, adress, SEEK_SET);
uint16 countoftags = 0;
if (read(fd_in, &countoftags, 2) != 2) perror ("input file not readable, countoftags");
if (
(countoftags > 4) &&
((countoftags *12 + adress)+4 < filesize )
) {
printf("IFD at adress 0x%x\n", adress);
uint32 nextifd = 0;
lseek( fd_in, 12*countoftags, SEEK_CUR);
if (read(fd_in, &nextifd, 4) != 4) perror("input file not readable, nextifd");
if (0 == nextifd) { printf("no next IFD found, all fine\n"); }
else { printf("IFD points to next IFD = 0x%0x\n", nextifd); }
printf("found %i Tags\n", countoftags);
lseek( fd_in, adress
+ 2 /* countoftags */
, SEEK_SET);
for (int i = 1; i <countoftags; i++) {
uint16 tagid = 0;
uint16 fieldtype = 0;
uint32 count = 0;
uint32 value_or_offset = 0;
if (read(fd_in, &tagid, 2) != 2) perror ("input file not readable, tagids");
printf("\tfound TAG 0x%0x (%u), ", tagid, tagid);
if (read(fd_in, &fieldtype, 2) != 2) perror ("input file not readable, fieldtypes");
printf("type=%2i, ", fieldtype);
if (read(fd_in, &count, 4) != 4) perror ("input file not readable, count");
printf("count=%32u, ", count);
if (read(fd_in, &value_or_offset, 4) != 4) perror ("input file not readable, count");
printf("value/offset=%32u (0x%08x)\n", value_or_offset, value_or_offset);
}
}
/* close infile */
close( fd_in );
}


/** help function */
void help () {
printf ("print_ifd_at_adress\n");
printf ("call it with:\n");
printf ("\tprint_ifd_at_adress [-h] -i <infile> [-a <adress>]\n");
printf ("\t where <infile> is the (broken) TIFF file\n");
}

int main (int argc, char * argv[]) {
const char *infilename = NULL;
uint32 address=0;
int c;
while ((c = getopt (argc, argv, "hi:a:")) != -1) {
switch (c)
{
case 'h': /* help */
help();
exit (0);
case 'i': /* expects infile */
infilename=optarg;
break;
case 'a': /* expects outfile */
printf("'%s'\n", optarg);
sscanf(optarg, "0x%x", &address);
break;
default:
abort();
}
}

if (NULL == infilename) {
fprintf (stderr, "You need to specify infile with '-i filename', see '%s -h' for details\n", argv[0]);
exit (FIXIT_TIFF_MISSED_INFILE);
}

if (0 == address) {
fprintf (stderr, "You need to specify address with '-a 0xff', see '%s -h' for details\n", argv[0]);
exit (-1);
}
print_ifd_at_adress( infilename, address);
}

Loading…
Cancel
Save