"checkit_tiff" is an incredibly fast conformance checker for baseline TIFFs (with various 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.
 
 
 
 
 
 

214 lines
6.6 KiB

  1. /* rule based checks if given TIFF is a specific baseline TIFF
  2. *
  3. * author: Andreas Romeyke, 2015
  4. * licensed under conditions of libtiff
  5. * (see http://libtiff.maptools.org/misc.html)
  6. *
  7. */
  8. #include "config_parser.h"
  9. #include "check.h"
  10. #include "check_helper.h"
  11. #include <unistd.h>
  12. #include <assert.h>
  13. #include <dirent.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #ifdef __unix__
  19. #include <unistd.h>
  20. #include <sys/stat.h>
  21. #include <sys/types.h>
  22. #else
  23. /* #include <sys\stat.h> */
  24. #include <sys/stat.h>
  25. #endif
  26. #define FLAGGED 1
  27. #define UNFLAGGED 0
  28. /** help function */
  29. void help () {
  30. printf ("checkit_tiff\n");
  31. printf ("\tversion: %s\n", VERSION);
  32. printf ("\trevision: %s\n", REPO_REVISION);
  33. printf("licensed under conditions of libtiff (see http://libtiff.maptools.org/misc.html)\n\n");
  34. printf ("\tuses libtiff version %s\n\n", TIFFGetVersion());
  35. printf ("call it with:\n");
  36. printf ("\tcheckit_tiff [-c|-h|-m|-d] <tifffile> <configfile>\n");
  37. printf ("\nwhere <tifffile> is the tiff file (or directory) to be validated\n");
  38. printf ("and <configfile> is the file name of the validation profile\n");
  39. printf ("\t-h this help\n");
  40. printf ("\t-c colorized output using ANSI escape sequences\n");
  41. printf ("\t-m uses memmapped I/O (faster validation, but needs more RAM)\n");
  42. printf ("\t-d check all files in that directory\n");
  43. printf ("example:\n\tcheckit_tiff tiffs_should_pass/minimal_valid.tiff example_configs/baseline_minimal.cfg\n");
  44. printf ("\n");
  45. }
  46. int check_specific_tiff_file( const char * tiff_file, int use_memmapped) {
  47. // printf("tiff file=%s\n", tiff_file);
  48. tif_files(tiff_file);
  49. /* load tiff file */
  50. TIFF* tif = NULL;
  51. if (use_memmapped == FLAGGED) {
  52. tif = TIFFOpen(tiff_file, "rM");
  53. } else { /* slow */
  54. tif = TIFFOpen( tiff_file, "rm");
  55. }
  56. if (NULL == tif) {
  57. fprintf( stderr, "file '%s' could not be opened\n", tiff_file);
  58. return (EXIT_FAILURE);
  59. };
  60. int is_valid = 0;
  61. ret_t res;
  62. /* special checks */
  63. res = check_all_IFDs_are_word_aligned( tif); if (0 != res.returncode) {is_valid++;}
  64. free (res.returnmsg);
  65. res = check_has_only_one_ifd( tif); if (0 != res.returncode) {is_valid++;}
  66. free (res.returnmsg);
  67. res = check_tagorder( tif); if (0 != res.returncode) {is_valid++;}
  68. free (res.returnmsg);
  69. res = check_all_offsets_are_used_once_only( tif ); if (0 != res.returncode) {is_valid++;}
  70. free (res.returnmsg);
  71. res = check_all_offsets_are_word_aligned( tif ); if (0 != res.returncode) {is_valid++;}
  72. free (res.returnmsg);
  73. res = check_tag_quiet( tif, TIFFTAG_DATETIME);
  74. free (res.returnmsg);
  75. if (res.returncode == 0) {
  76. res = check_datetime( tif );
  77. free (res.returnmsg);
  78. if (0 != res.returncode) {is_valid++;}
  79. }
  80. is_valid += execute_plan(tif);
  81. /* TODO: colorize? */
  82. if (is_valid > 0) {
  83. printf("found %i errors\n", is_valid);
  84. } else {
  85. printf("the given tif is valid\n");
  86. }
  87. //print_plan_results();
  88. TIFFClose(tif);
  89. return is_valid;
  90. }
  91. /** main */
  92. int main (int argc, char * argv[]) {
  93. printf("'%s' version: %s\n", argv[0], VERSION);
  94. printf ("\trevision: %s\n", REPO_REVISION);
  95. printf("licensed under conditions of libtiff (see http://libtiff.maptools.org/misc.html)\n");
  96. int c;
  97. int flag_check_directory=UNFLAGGED;
  98. int flag_use_memorymapped_io=UNFLAGGED;
  99. while ((c = getopt (argc, argv, "chmd")) != -1) {
  100. switch (c)
  101. {
  102. case 'h': /* help */
  103. help();
  104. exit (0);
  105. case 'c': /* colorize output */
  106. set_renderer_to_ansi();
  107. break;
  108. case 'd': /* check directory */
  109. flag_check_directory = FLAGGED;
  110. printf("\nCheck all files in given directory\n");
  111. break;
  112. case 'm': /* use memory mapped I/O */
  113. flag_use_memorymapped_io=FLAGGED;
  114. break;
  115. case '?': /* something goes wrong */
  116. /*
  117. if (optopt == 'r') {
  118. fprintf (stderr, "Option -%c requires an argument.\n", optopt);
  119. return (-1);
  120. }
  121. else*/ if (isprint (optopt)) {
  122. fprintf (stderr, "Unknown option `-%c'.\n", optopt);
  123. return (-1);
  124. }
  125. else if (0 !=optopt) {
  126. fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
  127. return (-1);
  128. }
  129. break;
  130. default:
  131. abort();
  132. }
  133. }
  134. if (argc - optind != 2) {
  135. help();
  136. fprintf( stderr, "%s needs at least two arguments, first should be the tiff-filename, second the config-file, example:\n\t %s tiffs_should_pass/minimal_valid.tiff example_configs/baseline_minimal.cfg\n", argv[0], argv[0]);
  137. exit (EXIT_FAILURE);
  138. }
  139. const char *tiff_file_or_dir=argv[optind];
  140. const char *cfg_file=argv[optind+1];
  141. printf("cfg_file=%s\n", cfg_file);
  142. int is_valid = 0;
  143. if (flag_check_directory == FLAGGED) {
  144. /* iterate through all files */
  145. size_t len = strlen( tiff_file_or_dir);
  146. char tiff_dir [ len ];
  147. strncpy(tiff_dir, tiff_file_or_dir, len);
  148. tiff_dir[ len ] = 0;
  149. /* printf ("tiffdir='%s'\n\n", tiff_dir);*/
  150. DIR *dir;
  151. struct dirent *ent;
  152. /* remove trailing / */
  153. char *dirsuffix = strrchr(tiff_dir, '/');
  154. if (dirsuffix != NULL) { /* found a / */
  155. /* printf ("len = %i dir = '%s' dirsuffix = '%s'\n", len, tiff_dir, dirsuffix);*/
  156. if ( 0 == strcmp( dirsuffix, "/" ) ) { /* ok, ends with / */
  157. /* remove last / */
  158. assert(len >= 1); // or whatever you want to do with short strings
  159. tiff_dir[len-1] = 0;
  160. /* printf("tiffdir2 = '%s'\n", tiff_dir); */
  161. }
  162. }
  163. /* iterate through all files in given dir */
  164. if ((dir = opendir (tiff_file_or_dir)) != NULL) {
  165. /* print all the files and directories within directory */
  166. while ((ent = readdir (dir)) != NULL) {
  167. struct stat attribute;
  168. int len = strlen( tiff_dir ) + strlen( ent->d_name ) + 2;
  169. char fqname [ len ];
  170. snprintf( fqname, len, "%s/%s", tiff_dir, ent->d_name);
  171. if (stat( fqname, &attribute) == -1) {
  172. fprintf (stderr, "could not stat on file '%s' in directory '%s' (%s)\n", ent->d_name, tiff_dir, fqname);
  173. exit(EXIT_FAILURE);
  174. }
  175. if(attribute.st_mode & S_IFREG) {
  176. /* printf ("%s\n", fqname); */
  177. parse_plan_via_file(cfg_file);
  178. is_valid += check_specific_tiff_file( fqname, flag_use_memorymapped_io);
  179. clean_plan();
  180. printf("\n");
  181. }
  182. }
  183. closedir (dir);
  184. } else {
  185. /* could not open directory */
  186. fprintf( stderr, "directory '%s' could not be opened\n", tiff_file_or_dir);
  187. exit(EXIT_FAILURE);
  188. }
  189. } else {
  190. /* use tiff_file_or_dir */
  191. parse_plan_via_file(cfg_file);
  192. is_valid = check_specific_tiff_file( tiff_file_or_dir, flag_use_memorymapped_io);
  193. clean_plan();
  194. }
  195. if (0 == is_valid) {
  196. exit(EXIT_SUCCESS);
  197. } else {
  198. exit(EXIT_FAILURE);
  199. }
  200. }